Ajax: async javascript and xml 非同步的JS和XML AJAX 是一種用於創建快速動態網頁的技術。 通過在後臺與伺服器進行少量數據交換,AJAX 可以使網頁實現非同步更新。這意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新。傳統的網頁(不使用 AJAX)如果需 ...
Ajax: async javascript and xml 非同步的JS和XML
AJAX 是一種用於創建快速動態網頁的技術。 通過在後臺與伺服器進行少量數據交換,AJAX 可以使網頁實現非同步更新。這意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新。傳統的網頁(不使用 AJAX)如果需要更新內容,必需重載整個網頁面。
Ajax創建四步法
我們都知道一個完整的Ajax動態網頁的實現方法為:
var xhr = new XMLHttpRequest; xhr.open("get","url",true); xhr.onreasystatechange = function () { "code gose there"; } xhr.send(string);
下麵我們就詳細的解釋一下上述的四個步驟。
AJAX - 創建一個Ajax XMLHttpRequest 對象
XMLHttpRequest 是 AJAX 的基礎。
XmlHttpRequest 術語縮寫為XHR,中文可以解釋為可擴展超文本傳輸請求。
所有現代瀏覽器(IE7+、Firefox、Chrome、Safari 以及 Opera)均內建 XMLHttpRequest 對象。(IE5 和 IE6 使用 ActiveXObject)。
XMLHttpRequest 用於在後臺與伺服器交換數據。這意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新。
為了應對所有的現代瀏覽器,包括 IE5 和 IE6,請檢查瀏覽器是否支持 XMLHttpRequest 對象。如果支持,則創建 XMLHttpRequest 對象。如果不支持,則創建 ActiveXObject ::
function createXHR() { var xhr = null; if (window.XMLHttpRequest) { xhr = new XMLHttpRequest; } else { try { xhr = new ActiveXobject("Microsoft.XMLHTTP"); } catch (e) { try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { } } } return xhr; }
var xhr = createXHR();
知上面的createXHR()方法每創建一個xhr對象,都會把createXHR方法執行一遍。由於我們第一次執行的時候就已經知道該瀏覽器下支持哪個new方法。但是第二次執行createXHR方法的時候就仍需要再全部重新執行一遍。這顯然會增加系統的開銷。所以我們可以用惰性思想的編程方式把支持瀏覽器的那個new方法返回來,這樣就不需要每次執行時都把全部的代碼執行一遍。
優化代碼代碼如下:
function createXHR() { var xhr = null, flag = false, arr = [ function () { return new XMLHttpRequest; }, function () { return new ActiveXObject("Microsoft.XMLHTTP"); }, function () { return new ActiveXObject("Msxm12.XMLHTTP"); } ]; for (var i = 0; i < arr.length; i++) { var curFn = arr[i]; try { xhr = curFn(); //本次迴圈獲取的方法沒有出現錯誤:說明此方法是我想要的,我們下一次直接執行這個方法即可,,這就需要我把createXHR重寫為本次迴圈得到的方法(完成後不需要再判斷下麵的,直接退出迴圈即可) createXHR = curFn; flag = true; break; } catch (e) { //本次迴圈獲取的方法執行時出現錯誤:繼續執行下一次迴圈 } if (!flag) { throw new Error("your browser is not support ajax,please change your browser,try again!"); } } return xhr; }
var xhr = createXHR();
AJAX - 向伺服器發送請求
XMLHttpRequest 對象用於和伺服器交換數據。
當你的頁面全部載入完畢後,客戶端會通過 XMLHttpRequest 對象向伺服器請求數據,伺服器端接受數據並處理後,向客戶端反饋數據。
如需將請求發送到伺服器,我們使用 XMLHttpRequest 對象的 open() 和 send() 方法:
xhr.open(method,url,async);
xhr.send(string);
- 規定請求的類型、URL 以及是否非同步處理請求。
open(method,url,async)
method:請求的類型;GET 或 POST
url:文件在伺服器上的位置,該文件可以是任何類型的文件
async:true(非同步)或 false(同步)
- XMLHttpRequest 對象如果要用於 AJAX 的話,其 open() 方法的 async 參數必須設置為 true。因為當設置成false(即同步)時,JavaScript 會等到伺服器響應就緒才繼續執行。如果伺服器繁忙或緩慢,應用程式會掛起或停止。
設置為true後,JavaScript 無需等待伺服器的響應,而是:
在等待伺服器響應時執行其他腳本。
當響應就緒後對響應進行處理。
- send(string)
將請求發送到伺服器。
string:僅用於 POST 請求,send方法也可以不傳參數,不傳參數的話,表示不向伺服器發送請求數據
AJAX - 伺服器響應
由於 HTTP 響應是由服務端發出的,並且伺服器做出響應需要時間(比如網速慢等原因),所以我們需要監聽伺服器響應的狀態,然後才能進行處理。 獲取來自伺服器的響應,使用 XMLHttpRequest 對象的 responseText 或 responseXML 屬性。 - xhr.responseText屬性是獲取字元串形式的響應數據 - xhr.responseXML屬性是獲取XML形式的響應數據AJAX - onreadystatechange 事件
當發送一個請求後,客戶端需要確定這個請求什麼時候會完成,因此,XMLHttpRequest對象提供了 onreadystatechange 事件機制來捕獲請求的狀態,繼而實現響應。
當請求被髮送到伺服器時,我們需要執行一些基於響應的任務。每當 readyState改變時,就會觸發 onreadystatechange 事件。readyState 屬性存有 XMLHttpRequest 的狀態信息。
下麵是 XMLHttpRequest 對象的三個重要的屬性:
- xhr.onreadystatechange
存儲函數(或函數名),每當 readyState 屬性改變時,就會調用該函數。onreadystatechange
- xhr.readyState
存有 XMLHttpRequest 的狀態。從 0 到 4 發生變化。
0:UNSET 請求未初始化,還沒有調用open()。
1:OPENED 請求已經建立,但是還沒有發送,open()已被調用,還沒有調用send()。
2:HEADER_RECEIVED 請求已發送,已經調用send()函數。正在處理中(通常現在可以從響應中獲取內容頭)。
3:LOADING 請求在處理中;通常響應中已有部分數據可用了,沒有全部完成。
4:LOADED 響應已完成;響應主體的內容已經成功返回到客戶端(解析完成)
- xhr.status:HTTP狀態碼,描述了伺服器響應內容的狀態
200 OK /^2\d{2}/ (200或2開頭的數字) 都代表響應主體的內容已經成功返回了
301 永久重定向/永久轉移
302 臨時重定向/臨時轉移
304 本次獲取的內容是讀取緩存中的數據
400 客戶端傳遞給伺服器的參數出現錯誤
401 無許可權訪問
404 客戶端訪問的地址不存在
500 未知的伺服器錯誤
503 伺服器已經超出負荷
當 readyState 等於 4 且狀態為 200 時,表示響應已就緒:在 onreadystatechange 事件中,我們規定當伺服器響應已做好被處理的準備時所執行的任務。
編寫一個簡易的Ajax方法庫
由於每次編寫Ajax方法都需要寫下上面完整的Ajax四步,這無疑增加了我們的工作量。下麵我們來編寫一個一個Ajax方法,我們只需要調用這個方法就可以實現Ajax的XMLHttpRequest請求。
//ajax:實現AJAX請求的公共方法:當一個方法傳遞的參數值過多,而且不固定,我們使用對象統一傳值法(需把要傳遞的參數值都先放在一個對象options中,一起傳遞進去即可) function ajax(options) { var _default = { url : "", //請求的地址 type : "get", //請求的方式 dataType : "json", //設置請求回來的內容格式"json"(即json格式的對象)。"txt"就是字元串或json格式的字元串 async : true, //請求是同步還是非同步 data : null, //放在請求主體中的內容(POST) getHeaders : null, //當READYSTATE===2時執行的回調函數 success : null //當readystate===4時執行的回調函數 } for (var key in options) { if (options.hasOwnProperty(key)) { _default[key] = options[key]; } } //如果當前的請求方式是GET,我們需要在URL的末尾添加隨機數清除緩存 if (_default[type] === "get") { _deauult[url].indexOf("?") >= 0 ? _default[url] += "&" :_default[url] += "?"; _default[url] += "_=" + Math.random(); } var xhr = createXHR(); xhr.open(_default[type],_default[url],_default[async]); xhr.onreadystatechange = function () { if (/^2\d{2}$/.test(xhr.status)) { //想要在readystate=2的時候做一些操作,需要保證ajax是非同步請求 if (xhr.readyState === 2) { if (typeof(_default[getHeaders]) === "function") { _default[getHeaders].call(xhr); } } if (xhr.readyState == 4) { var val = xhr.responseText; if (_default.dataType === "json") { val = "JSON" in window ? JSON.parse(val) : eval("(" + val + ")"); } if (typeof(_default[success]) === "function") { _default[success].call(xhr,val); };//_default[success] && _default[success].call(xhr,val); } } } xhr.send(_default[data]);//向請求主體傳內容,但open方法中必須使用post請求方式 }