原生JavaScript下的Ajax
- 2020 年 3 月 18 日
- 筆記
-
概述
AJAX即asynchronous javascript and XML,中文翻譯是非同步的javascript和XML。是指一種創建互動式網頁應用、用於創建快速動態網頁的開發技術。
傳統的網頁(不使用 AJAX)如果需要更新內容,必須重載整個網頁頁面。
而AJAX通過在後台與伺服器進行少量數據交換,可以使網頁實現非同步更新。這意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新。
ajax包括以下幾步驟:
1、創建AJAX對象
2、發出HTTP請求
3、接收伺服器傳回的數據
4、更新網頁數據
概括起來,就是一句話,ajax通過原生的XMLHttpRequest
對象發出HTTP請求,得到伺服器返回的數據後,再進行處理.
儘管名稱如此,XMLHttpRequest
也可以用於獲取任何類型的數據,而不僅僅是XML,它甚至支援HTTP以外的協議(包括 file:// 和 FTP)。
XMLHttpRequest
對象創建和使用
-
創建
XMLHttpRequest
對象是AJAX的核心技術,這是由微軟首先引入的一個特性。
IE5是第一款引入XHR對象的瀏覽器。
在IE5中,XHR對象是通過MSXML庫中的一個ActiveX對象實現的,而IE7+及其他標準瀏覽器都支援原生的XHR對象
1 var xhr; 2 if(window.XMLHttpRequest){ 3 xhr = new XMLHttpRequest(); 4 }else{ 5 xhr = new ActiveXObject('Microsoft.XMLHTTP'); 6 }
-
初始化請求
創建好之後使用open方法初始化一個請求
1 open(method: string, url: string): void; 2 open(method: string, url: string, async: boolean, username?: string | null, password?: string | null): void;
參數
method
- 要使用的HTTP方法,比如「GET」、「POST」、「PUT」、「DELETE」、等。對於非HTTP(S) URL被忽略。
url
- 該URL相對於執行程式碼的當前頁面,且只能向同一個域中使用相同埠和協議的URL發送請求。如果URL與啟動請求的頁面有任何差別,都會引發安全錯誤
async
可選- 一個可選的布爾參數,默認為
true
,表示要不要非同步執行操作。如果值為false
,send()
方法直到收到答覆前不會返回。如果true
,已完成事務的通知可供事件監聽器使用。如果multipart
屬性為true
則這個必須為true
,否則將引發異常。 user
可選- 可選的用戶名用於認證用途;默認為
null
。 password
可選- 可選的密碼用於認證用途,默認為
null
。
-
發送請求
發送請求使用的是send方法
send(body?: Document | BodyInit | null): void;
如果是非同步請求(默認為非同步請求),則此方法會在請求發送後立即返回;如果是同步請求,則此方法直到響應到達後才會返回
1.GET方法,send()方法無參數,或參數為null;
2.POST方法,send()方法的參數為要發送的數據( Blob | BufferSource | FormData | URLSearchParams | ReadableStream<Uint8Array> | string)一般為FormData.
註:沒有設置頭部資訊的話,會默認發送帶有 "* / *"
的Accept
頭部。
-
接收響應
上邊幾個步驟設置完以後就可以接收伺服器響應回來的數據
一個完整的HTTP響應由狀態碼、響應頭集合和響應主體組成。在收到響應後,這些都可以通過XHR對象的屬性和方法使用
屬性有
responseText 作為響應主體被返回的文本(文本形式),如果請求未成功或尚未發送,則返回 null。 responseXML 返回一個 Document,如果響應的內容類型是'text/xml'或'application/xml',這個屬性中將保存著響應數據的XML DOM文檔,如果請求未成功、尚未發送或時不能被解析為 XML 或 HTML,則返回 null。 status 代表請求的響應狀態 readyState 代表請求的狀態碼
在接收到響應後,第一步是檢查status屬性,以確定響應已經成功返回。
一般來說,可以將HTTP狀態碼為200作為成功的標誌。
此時,responseText屬性的內容已經就緒,而且在內容類型正確的情況下,responseXML也可以訪問了。
此外,狀態碼為304表示請求的資源並沒有被修改,可以直接使用瀏覽器中快取的版本;當然,也意味著響應是有效的
無論內容類型是什麼,響應主體的內容都會保存到responseText屬性中,而對於非XML數據而言,responseXML屬性的值將為null
1 xhr.onreadystatechange = function () { 2 if((xhr.status >=200 && xhr.status < 300) || xhr.status == 304){ 3 console.log(xhr.responseText); 4 }else{ 5 alert('request was unsuccessful:' + xhr.status); 6 } 7 if (xhr.readyState === 4) { 8 if (xhr.status == 200) { 9 console.log(xhr.responseText); 10 } 11 } 12 }
這裡要注意一下超時的問題
-
超時
XHR對象的timeout屬性等於一個整數,表示多少毫秒後,如果請求仍然沒有得到結果,就會自動終止。該屬性默認等於0,表示沒有時間限制
如果請求超時,將觸發ontimeout事件需要在send之後狀態碼改變之前使用
xhr.ontimeout = function () { console.log('The request timed out.'); } xhr.timeout = 1000;
[注意]IE8-瀏覽器不支援該屬性
-
最後
AJAX本身並不難,主要的就是有一部分內容涉及到網路方面的知識,所以導致學起來有一定的難度。
[注意]如果要建立N個不同的請求,就要使用N個不同的XHR對象。當然可以重用已存在的XHR對象,但這會終止之前通過該對象掛起的任何請求
HTTP協議有一個天生的缺陷:通訊只能由客戶端發起,因此HTTP協議做不到伺服器主動向客戶端推送資訊