Ajax關於readyState(狀態值)和status(狀態碼)的研究
var getXmlHttpRequest = function () { try{ //主流瀏覽器提供了XMLHttpRequest對象 return new XMLHttpRequest(); }catch(e){ //低版本的IE瀏覽器沒有提供XMLHttpRequest對象,IE6以下 //所以必須使用IE瀏覽器的特定實現ActiveXObject return new ActiveXObject("Microsoft.XMLHTTP"); } }; var xhr = getXmlHttpRequest(); // readyState 0=>初始化 1=>載入 2=>載入完成 3=>解析 4=>完成 // console.log(xhr.readyState); 0 xhr.open("TYPE", "URL", true); // console.log(xhr.readyState); 1 xhr.send(); // console.log(xhr.readyState); 1 xhr.onreadystatechange = function () { // console.log(xhr.status); //HTTP狀態嗎 // console.log(xhr.readyState); 2 3 4 if(xhr.readyState === 4 && xhr.status === 200){ alert(xhr.responseText); } };
1.Ajax:readyState(狀態值)和status(狀態碼)的區別
readyState,是指運行AJAX所經歷過的幾種狀態,無論訪問是否成功都將響應的步驟,可以理解成為AJAX運行步驟,使用“ajax.readyState”獲得
status,是指無論AJAX訪問是否成功,由HTTP協議根據所提交的信息,服務器所返回的HTTP頭信息代碼,使用“ajax.status”獲得
總體理解:可以簡單的理解為state代表一個整體的狀態。而status是這個大的state下面具體的小的狀態。
2.什麽是readyState
readyState是XMLHttpRequest對象的一個屬性,用來標識當前XMLHttpRequest對象處於什麽狀態。
readyState總共有5個狀態值,分別為0~4,每個值代表了不同的含義
0
:初始化,XMLHttpRequest對象還沒有完成初始化
1
:載入,XMLHttpRequest對象開始發送請求
2
:載入完成,XMLHttpRequest對象的請求發送完成
3
:解析,XMLHttpRequest對象開始讀取服務器的響應
4
:完成,XMLHttpRequest對象讀取服務器響應結束
3.什麽是status
status是XMLHttpRequest對象的一個屬性,表示響應的HTTP狀態碼
在HTTP1.1協議下,HTTP狀態碼總共可分為5大類
1
xx:信息響應類,表示接收到請求並且繼續處理
2
xx:處理成功響應類,表示動作被成功接收、理解和接受
3
xx:重定向響應類,為了完成指定的動作,必須接受進一步處理
4
xx:客戶端錯誤,客戶請求包含語法錯誤或者是不能正確執行
5
xx:服務端錯誤,服務器不能正確執行一個正確的請求
100
——客戶必須繼續發出請求
101
——客戶要求服務器根據請求轉換HTTP協議版本
200
——交易成功
201
——提示知道新文件的URL
202
——接受和處理、但處理未完成
203
——返回信息不確定或不完整
204
——請求收到,但返回信息為空
205
——服務器完成了請求,用戶代理必須復位當前已經瀏覽過的文件
206
——服務器已經完成了部分用戶的GET請求
300
——請求的資源可在多處得到
301
——刪除請求數據
302
——在其他地址發現了請求數據
303
——建議客戶訪問其他URL或訪問方式
304
——客戶端已經執行了GET,但文件未變化
305
——請求的資源必須從服務器指定的地址得到
306
——前一版本HTTP中使用的代碼,現行版本中不再使用
307
——申明請求的資源臨時性刪除
400
——錯誤請求,如語法錯誤
401
——請求授權失敗
402
——保留有效ChargeTo頭響應
403
——請求不允許
404
——沒有發現文件、查詢或URl
405
——用戶在Request-Line字段定義的方法不允許
406
——根據用戶發送的Accept拖,請求資源不可訪問
407
——類似
401
,用戶必須首先在代理服務器上得到授權
408
——客戶端沒有在用戶指定的餓時間內完成請求
409
——對當前資源狀態,請求不能完成
410
——服務器上不再有此資源且無進一步的參考地址
411
——服務器拒絕用戶定義的Content-Length屬性請求
412
——一個或多個請求頭字段在當前請求中錯誤
413
——請求的資源大於服務器允許的大小
414
——請求的資源URL長於服務器允許的長度
415
——請求資源不支持請求項目格式
416
——請求中包含Range請求頭字段,在當前請求資源範圍內沒有range指示值,請求也不包含If-Range請求頭字段
417
——服務器不滿足請求Expect頭字段指定的期望值,如果是代理服務器,可能是下一級服務器不能滿足請求
500
——服務器產生內部錯誤
501
——服務器不支持請求的函數
502
——服務器暫時不可用,有時是為了防止發生系統過載
503
——服務器過載或暫停維修
504
——關口過載,服務器使用另一個關口或服務來響應用戶,等待時間設定值較長
505
——服務器不支持或拒絕支請求頭中指定的HTTP版本
4.思考問題:為什麽onreadystatechange的函數實現要同時判斷readyState和status呢?
第一種思考方式:只使用readyState
var getXmlHttpRequest = function () { if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else if (window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); } }; var xhr = getXmlHttpRequest(); xhr.open("get", "1.txt", true); xhr.send(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { alert(xhr.responseText); } };
服務響應出錯了,但還是返回了信息,這並不是我們想要的結果
如果返回不是200,而是404或者500,由於只使用readystate做判斷,它不理會放回的結果是200、404還是500,只要響應成功返回了,就執行接下來的javascript代碼,結果將造成各種不可預料的錯誤。所以只使用readyState判斷是行不通的。
第二種思考方式:只使用status判斷
var getXmlHttpRequest = function () { try{ return new XMLHttpRequest(); }catch(e){ return new ActiveXObject("Microsoft.XMLHTTP"); } }; var xhr = getXmlHttpRequest(); xhr.open("get", "1.txt", true); xhr.send(); xhr.onreadystatechange = function () { if (xhr.status === 200) { alert("readyState=" + xhr.readyState + xhr.responseText); } };
事實上,結果卻不像預期那樣。響應碼確實是返回了200,但是總共彈出了3次窗口!第一次是“readyState=2”的窗口,第二次是“readyState=3”的窗口,第三次是“readyState=4”的窗口。由此,可見onreadystatechange函數的執行不是只在readyState變為4的時候觸發的,而是readyState(2、3、4)的每次變化都會觸發,所以就出現了前面說的那種情況。可見,單獨使用status判斷也是行不通的。
5.由上面的試驗,我們可以知道判斷的時候readyState和status缺一不可。那麽readyState和status的先後判斷順序會不會有影響呢?我們可以將status調到前面先判斷,代碼如 xhr.status === 200 && xhr.readyState === 4
事實上,這對於最終的結果是沒有影響的,但是中間的性能就不同了。由試驗我們知道,readyState的每次變化都會觸發onreadystatechange函數,假如先判斷status,那麽每次都會多判斷一次status的狀態。雖然性能上影響甚微,不過還是應該抱著追求極致代碼的想法,把readyState的判斷放在前面。
xhr.readyState === 4 && xhr.status === 200
Ajax關於readyState(狀態值)和status(狀態碼)的研究