最近在項目中經常會使用Ajax技術,用法上倒是熟練了,但是只知其然,不知其所以然,抽時間讀了讀JavaScript高級程序設計中關于Ajax的介紹有了些初步的理解,在此總結一下。
什么是Ajax
Ajax是Asynchronous JavaScript and XML的縮寫,這一技術能夠向服務器請求額外的數據而無需卸載整個頁面,會帶來良好的用戶體驗。傳統的HTTP請求流程大概是這樣的,瀏覽器向服務器發送請求-〉服務器根據瀏覽器傳來數據生成response-〉服務器把response返回給瀏覽器-〉瀏覽器刷新整個頁面顯示最新數據,這個過程是同步的,順序執行。
AJAX 在瀏覽器與 Web 服務器之間使用異步數據傳輸(HTTP 請求)從服務器獲取數據,這里的異步是指脫離當前瀏覽器頁面的請求、加載等單獨執行,這意味著可以在不重新加載整個網頁的情況下,通過JavaScript接受服務器傳來的數據,然后操作DOM將新數據對網頁的某部分進行更新,使用Ajax最直觀的感受是向服務器獲取新數據不需要刷新頁面等待了。
XMLHttpRequest 對象
Ajax的核心是JavaScript對象XmlHttpRequest,這個對象為向服務器發送請求和解析服務器響應提供了流暢的接口。XmlHttpRequest可以使用JavaScript向服務器提出請求并處理響應,而不阻塞用戶。
XHR對象由IE5率先引入,在IE5中XHR對象是通過MSXML庫中一個ActiveX對象實現的,根據IE版本不同可能會遇到不同版本XHR對象,而IE7+與其它現代瀏覽器均支持原生的XHR對象,在這些瀏覽器中我們只需使用XMLHttpRequest構造函數就可以構造XHR對象,因此一個瀏覽器兼容的創建XHR對象的函數寫法大概是這個樣子
<script type="text/javascript"> function createXHR(){ var xhr = null; try { // Firefox, Opera 8.0+, Safari,IE7+ xhr = new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { xhr = null; } } } return xhr; } </script>
XHR對象用法
XHR對象有兩個重要方法 open與send
在使用XHR對象時要調用的第一個方法是open方法,調用方式:xhr.open(“get”,”default.aspx”,true); 這段代碼會針對default.aspx頁面發送get請求,關于這段代碼有三點需要注意:
1. URL是相對于當前頁面的路徑,也可以使用絕對路徑
2. 調用open方法并不會真正的發送請求,而是初始化一個請求準備發送
3. 只能向同一個域中使用相同協議和端口的URL發送請求,否則會因為安全原因報錯
要想把請求發往服務器需要調用send方法,send方法接受一個參數,參數是請求主體要發送的數據,如果不需要發送數據則傳入null,在調用send方法之后請求被發往服務器,如下
xhr.send(null);
請求發往服務器,服務器根據請求生成響應(Response),傳回給XHR對象,在收到響應后相應數據會填充到XHR對象的屬性,有四個相關屬性會被填充:
1. responseText:作為響應主體被返回的文本
2. responseXML:如果響應內容的類型是”text/xml”或”application/xml”,這個屬性將保存包含著相應數據的XML文檔
3. status:響應的HTTP狀態(200,404,500等)
4. statusText:HTTP狀態說明
在收到響應后第一步是檢查響應狀態,確保響應是否成功返回(狀態為200),如果成功responseText和responseXML可以被訪問,為了確保響應有效,我們可以這樣檢查狀態碼
xhr.open('get','default.aspx,false'); //準備同步請求 xhr.send(); if(xhr.status>=200 && xhr.status<300 || xhr.status==304){ //do something }else{ //error handler }
上面代碼在發送同步請求的時候沒問題,只有得到響應后才會執行檢查status語句,但是在異步請求時,JavaScript會繼續執行,不等生成響應就檢查狀態碼,這樣我們不能保證檢查狀態碼語句是在得到響應后執行(實際上也幾乎不可能,服務器再快一個HTTP請求也不會快過一條JavaScript執行數度),這時候我們可以檢查XHR對象的readyState屬性,該屬性表示請求/響應過程中的當前活動階段,每當readyState值改變的時候都會觸發一次onreadystatechange事件。
我們可以利用這個事件檢查每次readyState變化的值,當為4的時候表示所有數據準備就緒,有一點我們需要注意:必須在open方法之前指定onreadtstatechange事件處理程序。
var xhr =createXHR(); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { setContainer('Original Ajax: ' + xhr.responseText); } } xhr.open('get', 'ajax.aspx?action=getTime', true); xhr.send();
我們可以在接受響應之前調用abort方法取消異步請求:xhr.abort();
HTTP Header
每個HTTP請求都會帶有Header信息,XHR對象也提供了操作這請求Header和響應Header信息的方法,在默認情況下,發送HTTP請求還會發送下列頭部信息
1. Accept:瀏覽器能夠處理的內容類型
2. Accept-Charset:瀏覽器能夠處理的字符集
3. Accept-Encoding:瀏覽器能夠處理的壓縮編碼
4. Accept-Language:瀏覽器當前設置的語言
5. Connection:瀏覽器與服務器的連接類型
6. Cookie:當前頁面的cookie
7. Referer:發送請求的頁面的URI
可以使用setRequestHeader方法設置自定義的請求Header信息,這個方法接受兩個參數:頭部字段的名稱,頭部字段的值。要想成功發送頭部信息,必須在調用open方法之后,調用send方法之前掉用setRequestHeader方法。
function getTime() { var xhr = createXHR(); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { setContainer('Original Ajax: ' + xhr.responseText); } } xhr.open('get', 'ajax.aspx?action=getTime', true); xhr.setRequestHeader(myHeader,myValue) xhr.send(); }
我們可以在服務器端接收自定義Header然后做響應操作。同時在服務器端也可以向瀏覽器發送額外的數據,在沒有自定義信息的情況下我們可以得到默認response header
1. Date:響應時間
2. Server:服務器類型
3. Very:驗證Encoding類型
4.X-Power-By:語言
。。。
GET和POST請求
GET請求時最常見的請求類型,用于向服務器查詢信息,必要時可以將查詢字符串參數放在URL尾部發送給服務器,如果參數有特殊字符必須正確編碼。我們上面使用的例子都是使用GET請求,非常簡單,向服務器詢問數據,然后處理數據。
POST請求用于把數據作為主體向服務器提交,POST請求主體可以包含多種格式數據,在open方法第一個參數傳入”POST”就可以初始化一個POST請求。發送POST請求第二步就是向send方法傳輸數據參數,參數可以是xml或者字符串,json等。
function getInfo() { var xhr = createXHR(); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { setContainer('Original Ajax: ' + xhr.responseText); } } xhr.open('post', 'default.aspx', true); xhr.send('{name:"Byron",age:"24"}'); }
最后
關于Ajax的總結就到這里,本文介紹的是純JavaScript使用Ajax很是繁瑣復雜,很多優秀JavaScript框架都對JavaScript操作Ajax做了很好封裝處理,使用起來非常方便,最出名的是jQuery的ajax了,微軟也對Ajax做了很好的分裝處理,使其在ASP.NET頁面中使用起來相當簡單方便,相關知識可以看看ASP.NET中使用Ajax。
文章列表