原生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,表示要不要非同步執行操作。如果值為falsesend()方法直到收到答覆前不會返回。如果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協議做不到伺服器主動向客戶端推送資訊

  它的這種單向請求的特點,註定了如果伺服器有連續的狀態變化,客戶端要獲知就必須採用輪詢的方式。而輪詢的效率低下且非常浪費資源,因為必須不停地連接或者讓HTTP連接始終打開。此時,也就出現了WebSocket。 
       之後會寫一下WebSocket API的用法