在前幾篇分析了jquery的ajax異步和同步,以及異常的一些處理,感覺還沒有把ajax的readyState和status說清楚.今天就來說說ajax狀態(tài)的那點事。
jquery ajax函數(shù)源代碼是這樣的:
var getXmlHttpRequest = function () {
if (window.XMLHttpRequest) {
//主流瀏覽器提供了XMLHttpRequest對象
return new XMLHttpRequest();
}
else if (window.ActiveXObject) {
//低版本的IE瀏覽器沒有提供XMLHttpRequest對象
//所以必須使用IE瀏覽器的特定實現(xiàn)ActiveXObject
return new ActiveXObject("Microsoft.XMLHTTP");
}
};
var xhr = getXmlHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 xhr.status === 200) {
//獲取成功后執(zhí)行操作
//數(shù)據(jù)在xhr.responseText
}
};
xhr.open("TYPE", "URL", true);
xhr.send("");
什么是readyState
readyState是XMLHttpRequest對象的一個屬性,用來標識當前XMLHttpRequest對象處于什么狀態(tài)。
readyState總共有5個狀態(tài)值,分別為0~4,每個值代表了不同的含義,如下表所示:
0 未初始化狀態(tài):此時,已經(jīng)創(chuàng)建了一個XMLHttpRequest對象
1 準備發(fā)送狀態(tài):此時,已經(jīng)調(diào)用了XMLHttpRequest對象的open方法,并且XMLHttpRequest對象已經(jīng)準備好將一個請求發(fā)送到服務(wù)器端
2 已經(jīng)發(fā)送狀態(tài):此時,已經(jīng)通過send方法把一個請求發(fā)送到服務(wù)器端,但是還沒有收到一個響應(yīng)
3 正在接收狀態(tài):此時,已經(jīng)接收到HTTP響應(yīng)頭部信息,但是消息體部分還沒有完全接收到
4 完成響應(yīng)狀態(tài):此時,已經(jīng)完成了HTTP響應(yīng)的接收
什么是status
status是XMLHttpRequest對象的一個屬性,表示響應(yīng)的HTTP狀態(tài)碼。
在HTTP1.1協(xié)議下,HTTP狀態(tài)碼總共可分為5大類,如下表所示:
1XX 服務(wù)器收到請求,需要繼續(xù)處理。例如101狀態(tài)碼,表示服務(wù)器將通知客戶端使用更高版本的HTTP協(xié)議。
2XX 請求成功。例如200狀態(tài)碼,表示請求所希望的響應(yīng)頭或數(shù)據(jù)體將隨此響應(yīng)返回。
3XX 重定向。例如302狀態(tài)碼,表示臨時重定向,請求將包含一個新的URL地址,客戶端將對新的地址進行GET請求。
4XX 客戶端錯誤。例如404狀態(tài)碼,表示客戶端請求的資源不存在。
5XX 服務(wù)器錯誤。例如500狀態(tài)碼,表示服務(wù)器遇到了一個未曾預料的情況,導致了它無法完成響應(yīng),一般來說,這個問題會在程序代碼出錯時出現(xiàn)。
拋出問題
為什么onreadystatechange的函數(shù)實現(xiàn)要同時判斷readyState和status呢?
我們知道 readyState === 4 已經(jīng)表示了請求響應(yīng)成功了,為什么還要后續(xù)的status呢?帶著問題,我們開始來做一些試驗吧。
只使用readyState判斷
javascript端的實現(xiàn)代碼如下:
var getXmlHttpRequest = function () {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
};
var xhr = getXmlHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
alert(xhr.responseText);
}
};
xhr.open("GET", "/data.aspx", true);
xhr.send("");
我們在服務(wù)端拋出異常:
public partial class data : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
throw new Exception("Error");
}
}
運行javascript代碼,提示窗口出現(xiàn)了如下:
服務(wù)響應(yīng)出錯了,但還是返回了信息,這并不是我們想要的結(jié)果。打開Fiddler監(jiān)控,可以看到data.aspx返回的是500響應(yīng),但由于只使用readystate做判斷,它不理會放回的結(jié)果是500還是200,只要響應(yīng)成功返回了,就執(zhí)行接下來的javascript代碼,結(jié)果將造成各種不可預料的錯誤。所以只使用readyState判斷是行不通的。
換另外一個角度想,狀態(tài)碼返回200就表示這次響應(yīng)是成功的了,那么是不是可以不使用readyState,單獨只使用status做判斷呢?好,帶著問題,繼續(xù)來做試驗吧。
只使用status判斷
javascript端的代碼實現(xiàn)如下:
var getXmlHttpRequest = function () {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
};
var xhr = getXmlHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.status === 200) {
alert("readyState=" + xhr.readyState + xhr.responseText);
}
};
xhr.open("GET", "/data.aspx", true);
xhr.send("");
事實上,結(jié)果卻不像預期那樣。響應(yīng)碼確實是返回了200,但是總共彈出了3次窗口!第一次是“readyState=2”的窗口,第二次是“readyState=3Test”的窗口,第三次是“readyState=4Test”的窗口。由此,可見onreadystatechange函數(shù)的執(zhí)行不是只在readyState變?yōu)?的時候觸發(fā)的,而是readyState的每次變化都會觸發(fā),所以就出現(xiàn)了前面說的那種情況??梢姡瑔为毷褂胹tatus判斷也是行不通的。
進一步思考
由上面的試驗,我們可以知道判斷的時候readyState和status缺一不可。那么readyState和status的先后判斷順序會不會有影響呢?我們可以將status調(diào)到前面先判斷,代碼如 xhr.status === 200 xhr.readyState === 4。
事實上,這對于最終的結(jié)果是沒有影響的,但是中間的性能就不同了。由上一個試驗我們知道,readyState的每次變化都會觸發(fā)onreadystatechange函數(shù),假如先判斷status,那么每次都會多判斷一次status的狀態(tài)。雖然性能上影響甚微,不過我們還是應(yīng)該抱著追求極致代碼的想法,把readyState的判斷放在前面。
以上所述是小編給大家介紹的jQuery Ajax的readyState和status的區(qū)別和使用詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
您可能感興趣的文章:- jQuery AJAX中readyState與status的區(qū)別與聯(lián)系
- 探討Ajax中有關(guān)readyState(狀態(tài)值)和status(狀態(tài)碼)的問題