前端學了有一段時間了,在項目中我通常使用的都是jQuery封裝好的Ajax函數($.ajax、$.get、$.post),使用非常的簡單方便,但為了更清楚的了解Ajax,需要學習原生xhr對象。
先來明確什么是Ajax,Ajax:“Asynchronous JavaScript and XML”,翻譯過來就是異步JavaScript和XML。
Ajax是一種用於創建快速動態網頁的技術,通過在后台與服務器進行少量數據交換,AJAX可以使網頁實現異步更新。意味這可以再不重新加載整個網頁的情況下,對網頁的某部分進行更新。
創建Ajax:
要創建Ajax,主角是XMLHttpRequest(下簡稱XHR)對象。
第一步:創建XHR對象
var xhr = new XMLHttpRequest();
第二步:向服務器發送請求
方法:open(method,url,async) 和 send(string)
open()方法傳入三參數
- method:請求的類型(GET/POST)
- url:文件在服務器上的位置
- async:布爾值,true表示異步,false表示同步(可選,默認為true)
send()方法將請求發送到服務器,有一個可選的參數string,僅用於POST類型的請求。
這里主要討論一下async參數,XMLHttpRequest對象如果要用於AJAX的話,其open()方法的async參數必須設置為true。那如果參數設置為false會有什么樣的后果呢?同步請求的后果是:JavaScript會等到服務器響應就緒才繼續執行。如果是比較大型的請求或者服務器處於繁忙狀態,應用程序會掛起或停止。簡單點說就是頁面會一直卡到響應內容回來才繼續運行。
在發送GET請求的時候,可能得到緩存的信息(IE中),導致我們發送的異步請求不能正確的返回我們想要的最新的數據。
方法一:在url中添加一個唯一的ID:(隨機數)
1 xhr.open("GET","demo.asp?t=" + Math.random(),true); 2 xhr.send();
這種方式可以避免拿到緩存中的舊消息,但它的每次請求仍然會被瀏覽器緩存起來,占用瀏覽器資源。
方法二:用setRequestHeader(header,value)方法向請求添加HTTP頭。(關於setRequestHeader在后面討論)
1 xhr.open("GET","demo.asp",true); 2 xhr.setRequestHeader("If-Modified-Since","0"); //設置瀏覽器不使用緩存 3 xhr.send();
GET中的url可以拼接字符串從而達到傳參,而傳送數據一般用POST。
如果我們用POST方法向服務器發送數據,應該這樣設置http頭。
1 xhr.open("POST","postdemo.asp",true); 2 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); //否則數據無法被正常接收 3 xhr.send("name=amie"); //send里寫要發送的數據
第三步:服務器響應
XMLHttpRequest對象的responseText和responseXML屬性分別獲得字符串形式的響應數據和XML形式的響應數據
可以在控制台里輸出響應
console.log(xhr.responseText);
還有三個關於響應狀態的屬性也經常用到:
- readyState:存有XMLHttpRequest的狀態。XHR對象會經歷5種不同的狀態
- 0:請求未初始化(new完后);
- 1:服務器連接已建立(對象已創建並初始化,尚未調用send方法);
- 2:請求已接收;
- 3:請求處理中;
- 4:請求已完成,響應就緒;
- status:(HTTP狀態碼很多,請自行了解,舉例常見的)
- 200:請求成功
- 404:未找到頁面
- onreadystatechange:存儲函數(或函數名),每當readyState屬性改變時,就會調用該函數。
因此上面那行代碼可以改為:
1 xhr.onreadystatechange = function () { 2 if (xhr.readyState == 4 && xhr.status == 200) { 3 console.log(xhr.responseText); 4 };
關於setRequestHeader
在HTTP協議里,客戶端向服務器請求某個網頁的時候,需要發送一個HTTP協議的頭文件,而XMLHttp就是通過HTTP協議去的網站上的文件數據的,所以也要發送HTTP頭給服務器。
發送請求時會默認發一個頭文件,如果我們需要修改或添加參數,就需要用到setRequestHeader方法。
Ps:
1.響應頭包含了許多信息,有興趣的小伙伴可以去了解一下。(HTTP涉及了許多計算機網絡的知識)。
2.查看http請求頭可以到開發者工具里的Network里查看。
(寫在結尾:前端新人一枚~歡迎大家指出錯誤,謝謝閱覽~)