Ajxa局部刷新用於提高用戶體驗。Ajax技術的核心是XMLHttpRequest對象(簡稱XHR)
- XMLHttpRequest對象
XMLHttpRequest對象在ie7及更高版本可以這樣申明。
var xhr=new XMLHttpRequest();
- XHR的用法
發送get請求寫法是這樣:
xhr.open(“get”,”example”,false); xhr.send(null);
由於這次請求時同步的,JavaScript代碼會等到服務器響應之后再繼續執行,在收到響應后,響應的數據會自動填充XHR對象的屬性,相關的屬性如下:
- responseText:作為響應主體返回的文本。
- responseXML:如果響應的內容類型是”text/xml”或”application/xml”,這個屬性中將保存包含着響應數據的XML DOM文檔。
- status:響應的HTTP狀態。
- statusText:HTTP狀態的說明。
在接收到響應后,第一步是檢查status屬性,以確定響應已經成功返回,為確保接收到適當的相應,應該像下面這樣寫:
xhr.open(“get”,”example.txt”,false); xhr.send(null); if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ alert(xhr.responseText); }else{ alert(“Request was unsuccessful:”+xhr.status); }
很多情況下,我們還是要發送異步請求,才能讓JavaScript繼續執行而不必等待響應,此時,可以檢測XHR對象的readyState屬性,該屬性表示請求/響應過程的當前活動階段:
- 0:未初始化,未調用open方法。
- 1:啟動,已經調用open方法,未調用send方法
- 2:發送,調用send方法,未接收到響應。
- 3:接收,已經接收到部分響應數據
- 4:完成
只要readyState屬性的值右一個值變成另一個值,都會觸發一次readystatechange事件,可以利用這個事件來檢測每次狀態變化后的readyState的值,通常我們只對readyState值為4的階段感興趣,不過必須在調用open之前指定onreadystatechange事件處理程序才能確保跨瀏覽器兼容性。代碼如下:
var xhr=createXHR(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ alert(xhr.responseText); }else{ alert(“request was unsuccessful:”+xhr.status); } } }; xhr.open(“get”,”sxample”,true); xhr.send(null);
以上代碼利用DOM0級方法為XHR對象添加了事件處理程序,原因是並非所有瀏覽器都支持DOM2級方法,與其他事件處理程序不同,這里沒有向onreadystatechange事件處理程序中傳遞event對象;必須通過XHR對象本身確定下一步該怎么做。
在接收到響應之前還可以調用abort()方法來取消異步請求,如下:
xhr.abort();
調用這個方法后,XHR對象會停止觸發事件,而且也不再允許訪問任何與響應有關的對象屬性,在終止請求之后,還應該對XHR對象進行解引用操作,不建議重用XHR對象。
- HTTP頭部信息
每個HTTP請求和響應都會帶有相應的頭部信息,頭部信息有:
- Accept:瀏覽器能夠處理的內容類型。
- Accept-Charset:瀏覽器能夠現實的字符集。
- Accept-Encoding:瀏覽器能處理的壓縮編碼。
- Accept-Language:瀏覽器當前設置的語言。
- Connection:瀏覽器與服務器之間的連接類型。
- Cookie:當前頁面設置的任何Cookie。
- Host:發出請求的頁面所在的域
- Referer:發出請求的頁面的URL。
- User-Agent:瀏覽器的用戶帶來字符串。
雖然不同瀏覽器實際發送的頭部信息會有所不同,但以上列出的基本上是所有瀏覽器都會發送的,使用setRequestHeader方法可以設置自定義的請求頭部信息,這個方法接受兩個參數:頭部字段的名稱和頭部字段的值。如:
var xhr=createXHR(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ alert(xhr.responseText); }else{ alert(“Request was unsuccessful:”+xhr.status); } } }; xhr.open(“get”,”example.php”,true); xhr.setRequestHeader(“MyHeader”,”MyValue”); xhr.send(null);
調用XHR對象的getResponseHeader方法並傳入頭部字段名稱,可以取得相應的響應頭部信息,而調用getAllResponseHeaders方法則可以取得一個包含所有頭部信息的長字符串。
- Get請求
Get是最常見的請求類型,可以將查詢字符串參數追加到URL的末尾,以便將信息發送給服務器,使用get請求經常會發送的一個錯誤就是查詢字符串的格式問題,查詢字符串中的每個參數名和值都必須使用encodeURIComponent進行編碼,然后在放到URL的末尾,而且所有名-值對都必須由&分隔。
- POST請求
使用頻率僅次於get,post請求應該把數據作為請求的主體提交,可以包含非常多的數據,而且格式不限,用過ajax來提交表單要先將Content-Type頭部信息設置為application/x-www-form-urlencoded,也就是表單提交時的內容類型。代碼如下:
function submitData(){ var xhr=createXHR(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ alert(xhr.responseText); }else{ alert(xhr.responseText); } } } }; xhr.open(“post”,postexample.php,true); xhr.setRequestHeader(“Content-Type”,”application/x-www-form-urlencoded”); var form=focument.getElementById(“user-info”); xhr.send(serialize(form));
- XMLHttpRequest 2級:FormData
FormData為序列化表單以及創建與表單格式相同的數據提供了便利。
var data=new FormData(); data.append(“name”,”Nicholas”); var data=new FormData(doucument.forms[0])
- 超時設定
表示請求在等待響應多少毫秒之后就終止,在給定的時間內瀏覽器還沒有接收到響應,那么就會觸發timeout事件,進而會調用ontimeout事件出來程序,代碼如下:
var xhr=createXHR(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ try{ if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ alert(xhr.responseText); }else{ alert(“Request was unsuccessful:”+xhr.status); } }catch(ex){ } } } xhr.open(“get”,”timeout.php”,true); xhr.timeout=1000; xhr.ontimeout=function(){ alert(“Request did not return in a second”); }; xhr.send(null);
- overrideMineType方法
用於重寫XHR響應的MIME類型,因為返回響應的MIME類型決定了XHR對象如何處理它,所以提供一種方法能夠重寫服務器返回的MIME類型是很有用的。例如:
var xhr=createXHR(); xhr.open(“get”,”text.php”,true); xhr.overrideMineType(“text/xml”); xhr.send(null);
- 進度事件
- load事件
響應接收完畢后將觸發load事件,因此也就沒有必要去檢查readystate屬性了,而onload事件處理程序會接收到一個event對象,其target屬性就指向xht對象實例。單並非所有瀏覽器都為這個事件實現了適當的事件對象。
var xhr=createXHR(); xhr.onload=function(){ if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ alert(xhr.responseText); }else{ alert(“request was unsuccessful:”+xhr.status); } }; xhr.open(“get”,”alrevents.php”,true); xhr.send(null);
- progress事件
這個事件會在瀏覽器接收新數據期間周期性的觸發,而onprogress事件處理程序會接收一個event對象,其target屬性是XHR對象,但包含着三個額外的屬性:lengthComputable、position和totalSize。LengthComputable是一個表示進度信息是否可用的布爾值,position表示已經接收的字節數,totalSize表示根據Content-Length響應頭部確定的預期字節數。
var xhr=createXHR(); xhr.onload=function(event){ if((xhr.status>=200&&xhr.status<300)||xhr.status==304){ alert(xhr.responseText); }else{ alert(“Request wa unsuccessful:”+xhr.status); } }; xhr.onprogress-function(event){ var divStatus=document.getElementById(“status”); if(event.lengthComputable){ if(event.lengthComputable){ divStatus.innerHTML=”Received ”+event.position+” of ”+event.totalSize+”bytes”; } } }; xhr.open(“get”,”altevents.php”,true); xhr.send(null);