作為一個(gè)后端人員,很慚愧,對(duì)Ajax的使用只局限在功能實(shí)現(xiàn)層面的交互,對(duì)底層通過XMLHttpRequest對(duì)象來使用的知識(shí)卻沒有仔細(xì)研究過?,F(xiàn)總結(jié)如下
var xmlhttp;if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); }else {// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); }
xmlhttp.open("GET","test1.txt",true); //規(guī)定請(qǐng)求的類型、URL 以及是否異步處理請(qǐng)求。xmlhttp.send(); //將請(qǐng)求發(fā)送到服務(wù)器。
open(method,url,async)
send(string)
如果需要像 HTML 表單那樣 POST 數(shù)據(jù),請(qǐng)使用 setRequestHeader() 來添加 HTTP 頭。然后在 send() 方法中規(guī)定您希望發(fā)送的數(shù)據(jù):
xmlhttp.setRequestHeader("content-type","text/xml;charset=utf-8"); //向請(qǐng)求中添加 HTTP 頭
setRequestHeader(header,value)
如需獲得來自服務(wù)器的響應(yīng),請(qǐng)使用 XMLHttpRequest 對(duì)象的 responseText 或 responseXML 屬性。
當(dāng)請(qǐng)求被發(fā)送到服務(wù)器時(shí),我們需要執(zhí)行一些基于響應(yīng)的任務(wù)。每當(dāng) readyState 改變時(shí),就會(huì)觸發(fā) onreadystatechange 事件。
通過之前的Ajax調(diào)用公網(wǎng)服務(wù)的代碼可以具體的了解XMLHttpRequest對(duì)象的使用。
var getXmlHttpRequest = function () { try{ //主流瀏覽器提供了XMLHttpRequest對(duì)象 return new XMLHttpRequest(); }catch(e){ //低版本的IE瀏覽器沒有提供XMLHttpRequest對(duì)象,IE6以下 //所以必須使用IE瀏覽器的特定實(shí)現(xiàn)ActiveXObject return new ActiveXObject("Microsoft.XMLHTTP"); } };//創(chuàng)建XMLHttpRequest對(duì)象var xhr = getXmlHttpRequest();//打開連接xhr.open("post","http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx",true);//設(shè)置數(shù)據(jù)類型xhr.setRequestHeader("content-type","text/xml;charset=utf-8");//設(shè)置回調(diào)函數(shù)xhr.onreadystatechange=function(){//判斷是否發(fā)送成功和判斷服務(wù)端是否響應(yīng)成功if(4 == xhr.readyState && 200 == xhr.status){ alert(xhr.responseText); }}//組織SOAP協(xié)議數(shù)據(jù) 篇幅原因,此處信息省略var soapXML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>···· ····"; //發(fā)送數(shù)據(jù)xhr.send(soapXML);
readyState,是指運(yùn)行AJAX所經(jīng)歷過的幾種狀態(tài),無論訪問是否成功都將響應(yīng)的步驟,可以理解成為AJAX運(yùn)行步驟,使用“ajax.readyState”獲得
status,是指無論AJAX訪問是否成功,由HTTP協(xié)議根據(jù)所提交的信息,服務(wù)器所返回的HTTP頭信息代碼,使用“ajax.status”獲得
總體理解:可以簡(jiǎn)單的理解為state代表一個(gè)整體的狀態(tài)。而status是這個(gè)大的state下面具體的小的狀態(tài)。
readyState是XMLHttpRequest對(duì)象的一個(gè)屬性,用來標(biāo)識(shí)當(dāng)前XMLHttpRequest對(duì)象處于什么狀態(tài)。
readyState總共有5個(gè)狀態(tài)值,分別為0~4,每個(gè)值代表了不同的含義
0:初始化,XMLHttpRequest對(duì)象還沒有完成初始化1:載入,XMLHttpRequest對(duì)象開始發(fā)送請(qǐng)求2:載入完成,XMLHttpRequest對(duì)象的請(qǐng)求發(fā)送完成3:解析,XMLHttpRequest對(duì)象開始讀取服務(wù)器的響應(yīng)4:完成,XMLHttpRequest對(duì)象讀取服務(wù)器響應(yīng)結(jié)束
status是XMLHttpRequest對(duì)象的一個(gè)屬性,表示響應(yīng)的HTTP狀態(tài)碼
在HTTP1.1協(xié)議下,HTTP狀態(tài)碼總共可分為5大類
1xx:信息響應(yīng)類,表示接收到請(qǐng)求并且繼續(xù)處理2xx:處理成功響應(yīng)類,表示動(dòng)作被成功接收、理解和接受3xx:重定向響應(yīng)類,為了完成指定的動(dòng)作,必須接受進(jìn)一步處理4xx:客戶端錯(cuò)誤,客戶請(qǐng)求包含語法錯(cuò)誤或者是不能正確執(zhí)行5xx:服務(wù)端錯(cuò)誤,服務(wù)器不能正確執(zhí)行一個(gè)正確的請(qǐng)求 100——客戶必須繼續(xù)發(fā)出請(qǐng)求101——客戶要求服務(wù)器根據(jù)請(qǐng)求轉(zhuǎn)換HTTP協(xié)議版本200——交易成功201——提示知道新文件的URL202——接受和處理、但處理未完成203——返回信息不確定或不完整204——請(qǐng)求收到,但返回信息為空205——服務(wù)器完成了請(qǐng)求,用戶代理必須復(fù)位當(dāng)前已經(jīng)瀏覽過的文件206——服務(wù)器已經(jīng)完成了部分用戶的GET請(qǐng)求300——請(qǐng)求的資源可在多處得到301——?jiǎng)h除請(qǐng)求數(shù)據(jù)302——在其他地址發(fā)現(xiàn)了請(qǐng)求數(shù)據(jù)303——建議客戶訪問其他URL或訪問方式304——客戶端已經(jīng)執(zhí)行了GET,但文件未變化305——請(qǐng)求的資源必須從服務(wù)器指定的地址得到306——前一版本HTTP中使用的代碼,現(xiàn)行版本中不再使用307——申明請(qǐng)求的資源臨時(shí)性刪除400——錯(cuò)誤請(qǐng)求,如語法錯(cuò)誤401——請(qǐng)求授權(quán)失敗402——保留有效ChargeTo頭響應(yīng)403——請(qǐng)求不允許404——沒有發(fā)現(xiàn)文件、查詢或URl405——用戶在Request-Line字段定義的方法不允許406——根據(jù)用戶發(fā)送的Accept拖,請(qǐng)求資源不可訪問407——類似401,用戶必須首先在代理服務(wù)器上得到授權(quán)408——客戶端沒有在用戶指定的餓時(shí)間內(nèi)完成請(qǐng)求409——對(duì)當(dāng)前資源狀態(tài),請(qǐng)求不能完成410——服務(wù)器上不再有此資源且無進(jìn)一步的參考地址411——服務(wù)器拒絕用戶定義的Content-Length屬性請(qǐng)求412——一個(gè)或多個(gè)請(qǐng)求頭字段在當(dāng)前請(qǐng)求中錯(cuò)誤413——請(qǐng)求的資源大于服務(wù)器允許的大小414——請(qǐng)求的資源URL長(zhǎng)于服務(wù)器允許的長(zhǎng)度415——請(qǐng)求資源不支持請(qǐng)求項(xiàng)目格式416——請(qǐng)求中包含Range請(qǐng)求頭字段,在當(dāng)前請(qǐng)求資源范圍內(nèi)沒有range指示值,請(qǐng)求也不包含If-Range請(qǐng)求頭字段417——服務(wù)器不滿足請(qǐng)求Expect頭字段指定的期望值,如果是代理服務(wù)器,可能是下一級(jí)服務(wù)器不能滿足請(qǐng)求500——服務(wù)器產(chǎn)生內(nèi)部錯(cuò)誤501——服務(wù)器不支持請(qǐng)求的函數(shù)502——服務(wù)器暫時(shí)不可用,有時(shí)是為了防止發(fā)生系統(tǒng)過載503——服務(wù)器過載或暫停維修504——關(guān)口過載,服務(wù)器使用另一個(gè)關(guān)口或服務(wù)來響應(yīng)用戶,等待時(shí)間設(shè)定值較長(zhǎng)505——服務(wù)器不支持或拒絕支請(qǐng)求頭中指定的HTTP版本
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); }};
服務(wù)響應(yīng)出錯(cuò)了,但還是返回了信息,這并不是我們想要的結(jié)果
如果返回不是200,而是404或者500,由于只使用readystate做判斷,它不理會(huì)放回的結(jié)果是200、404還是500,只要響應(yīng)成功返回了,就執(zhí)行接下來的javascript代碼,結(jié)果將造成各種不可預(yù)料的錯(cuò)誤。所以只使用readyState判斷是行不通的。
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); }};
事實(shí)上,結(jié)果卻不像預(yù)期那樣。響應(yīng)碼確實(shí)是返回了200,但是總共彈出了3次窗口!第一次是“readyState=2”的窗口,第二次是“readyState=3”的窗口,第三次是“readyState=4”的窗口。由此,可見onreadystatechange函數(shù)的執(zhí)行不是只在readyState變?yōu)?的時(shí)候觸發(fā)的,而是readyState(2、3、4)的每次變化都會(huì)觸發(fā),所以就出現(xiàn)了前面說的那種情況??梢姡瑔为?dú)使用status判斷也是行不通的。
由上面的試驗(yàn),我們可以知道判斷的時(shí)候readyState和status缺一不可。那么readyState和status的先后判斷順序會(huì)不會(huì)有影響呢?我們可以將status調(diào)到前面先判斷,代碼如 xhr.status == 200 && xhr.readyState == 4
事實(shí)上,這對(duì)于最終的結(jié)果是沒有影響的,但是中間的性能就不同了。由試驗(yàn)我們知道,readyState的每次變化都會(huì)觸發(fā)onreadystatechange函數(shù),假如先判斷status,那么每次都會(huì)多判斷一次status的狀態(tài)。雖然性能上影響甚微,不過還是應(yīng)該抱著追求極致代碼的想法,把readyState的判斷放在前面。
xhr.readyState == 4 && xhr.status == 200
聯(lián)系客服