AJAX問題之XMLHttpRequest status = 0

分類:IT技術 時間:2017-03-23
  • 原文地址 

    • http://blog.csdn.net/iaiti/article/details/42192659
  • 我的代碼  

error:function(XHR,textStatus,errorThrown){
            
            if (XHR.status == 403){
                // 全文替換 " 為 空字符串
                var errMsg = XHR.responseText.replace(/\"/g,"");
                swal({
                     title:errMsg,
                     text:'3 秒後自動關閉',
                     timer:3000,
                     type:'error'
                 });
            } else {
                swal({
                    title:'服務器內部錯誤,sorry!',
                    text:'3 秒後自動關閉',
                    timer:3000,
                    type:'error'
                });
            }

 

  • 原文內容

其實這篇文章要寫的不止是XMLHttpRequest status = 0 這個問題,還有我重新看AJAX遇到的一些問題和自己的反思。

 

先看整個例子:


<html>  
<head>  
<script type="text/Javascript">  
    var xmlhttp;  
    function loadXMLDoc(url) {  
        xmlhttp = null;  
        if (window.XMLHttpRequest) {// code for all new browsers  
            xmlhttp = new XMLHttpRequest();  
        } else if (window.ActiveXObject) {// code for IE5 and IE6  
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");  
        }  
  
        if (xmlhttp != null) {  
            xmlhttp.onreadystatechange = state_Change;  
            xmlhttp.open("GET", url, true);  
            xmlhttp.send(null);  
        }  
    }  
  
    function state_Change() {  
        if (xmlhttp.readyState == 4) {  
            alert(xmlhttp.status);  
            alert(xmlhttp.responseText);  
            if (xmlhttp.status == 200) {  
                alert("200");  
            } else {  
                alert(xmlhttp.status);  
                alert("Problem retrieving XML data");  
            }  
        }  
    }  
</script>  
<title>Document</title>  
<button onclick="loadXMLDoc('file:///E:/test2.html')">click</button>  
</head>  
<body>  
</body>  
</html>  


 

1、為什麽是xmlhttp.onreadystatechange = state_Change而不是xmlhttp.onreadystatechange = state_Change();

調用函數不是要用()寫明的嗎?難道它會根據函數名去找函數?問了幾個前端的,感覺對這個都是模模糊糊也不懂真正的原因在哪裏,最後還是去請教了另外一位師兄。

 

為的是把整個函數給onreadystatechange,而不是將函數最後處理完的值返回給onreadystatechange。

 

再來理一遍思路,XMLHttpRequest對象是在我最近在重看xml的教程時看到了,立刻和AJAX聯系在一起。

w3c這樣描述,它用於後臺與服務器交換數據,是開發者的夢想

 

現在的瀏覽器直接可以通過new拿到對象,但是IE就不可以了,xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

同時在IE6運行的時候瀏覽器會提示你設置ActiveX。

 

onreadystatechange是一個事件句柄,同樣功能的還有onclick這些,就是有點擊事件的時候會進行特定處理,具體看你的函數怎麽寫了。而onreadystatechange是由readyState觸發,readyState存著XMLHttpRequest的狀態,

 0: 請求未初始化
 1: 服務器連接已建立
 2: 請求已接收
 3: 請求處理中
 4: 請求已完成,且響應已就緒

readyState改變,調用onreadystatechange這個函數,註意,是這個函數,那我們是不是要賦值一個函數給他,而不是單純地返回一個值。

 

所以,問題解決了。

同時不同於:

<button onclick="dodo()">click</button>  

這個是HTML裏面的,雖然也是事件句柄,但是格式不同。上面那個是在JS代碼裏面的。

2、XMLHttpRequest status = 0 問題。

xmlhttp.readyState =4的時候,一直xmlhttp.status != 200。便隨手輸出,發現xmlhttp.status=0,http協議裏可是沒這個狀態碼的。最後翻啊翻啊,找啊找啊,最後找到一個XMLHttpRequest的說明:http://www.w3.org/TR/XMLHttpRequest/ 。

The status attribute must return the result of running these steps:

status的值一定會返回運行這些步驟的結果。

 

1、If the state is UNSENT or OPENED, return 0.(如果狀態是UNSENT或者OPENED,返回0)
2、If the error flag is set, return 0.(如果錯誤標簽被設置,返回0)
3、Return the HTTP status code.(返回HTTP狀態碼)

如果在HTTP返回之前就出現上面兩種情況,就出現0了。

先說兩個button,一個是url是:file:///E:/test2.html,另外一個是:http://www.baidu.com。

第一個button的url訪問只是本地打開沒有通過服務器,自己可以用Wireshark捉包(感謝某位高人指點)。

這裏面還有一個問題,就是xmlhttp.readyState一直會變,

1: 服務器連接已建立

2: 請求已接收  

3: 請求處理中  

4: 請求已完成,且響應已就緒。

以這種情況看的話,應該是xmlhttp自己在模擬,因為根本就沒通過服務器。本地直接打開而已。OPENED了,所以status為0。

 

第二個button的url訪問雖然是其他域名,抓包是有的,但是,這是跨域訪問了,

If the cross-origin request status is Network error

    This is a network error.

雖然去訪問了,應該是瀏覽器跨域的返回頭沒有允許,所以瀏覽器阻止, Access-Control-Allow-Origin這個屬性。

 

真確的方法是在自己的服務器,訪問自己域名內的url。

在tomcat上跑:

<button onclick="loadXMLDoc('http://localhost:8080/TestServlet/MyServlet')">click</button>  

最後我在反思,我自己一直在尋求問題的答案,但是問其中一些人的時候,只是給出了自己隨手百度而來的答案,有些人,甚至我說加括號之後有錯了之後就不再理會這個問題,會用就行了。但是我不止於這種答案,還是去問了一個師兄,因為,這位師兄前端了得,重要的是,是一位技術愛好者,就是他把第一個問題的分析給我聽,後面自己去Google再深入。

 

搞技術的差距,大概於此,現在可能差距不大,但是幾年之後,估計就不是一個級別了。

人之差距,也是如此罷了。

 

最後要感謝另外一個人,他讓我見識到了了一個全棧工程師的。前後端通殺,底層也會,業務邏輯也會。幾句話能把我下午查的東西串聯起來,所謂真正的程序員,也是如此。與他的一番談話,很是興奮,也甚是佩服。熱愛技術的人,不過與此。


Tags: javascript function status 服務器 字符串

文章來源:


ads
ads

相關文章
ads

相關文章

ad