ajax請求相關

上一篇單獨寫的是ajax跨域,這一篇就來詳細說一說ajax,ajax是現代web開發中必不可少的一部分內容,非常基礎也非常重要,這篇總結一下到目前為止我對ajax的理解。

什麼是ajax

ajax是web開發中的一種交互技術,全稱為Asynchronous JavaScript And XMLHttpRequest,使用ajax可以實現頁面局部更新,每次變化不再需要請求整個頁面,之前在我web開發歷史的文章中也提到過,從前的web頁面每次需要更新時都必須要刷新整個頁面,整體體驗非常不好。ajax的出現並大量使用在web開發中絕對是顛覆性的變化,它使得開發出優秀的web應用成為現實,從此各種各樣的前端技術才得以興起。時至今日,ajax已經成為web開發中難以或缺的一部分。

ajax的核心自然就是XMLHttpRequest對象了,它存在於所有現代瀏覽器中(IE5 和 IE6 使用 ActiveXObject),它使得瀏覽器可以發出HTTP請求與接收HTTP響應。有了這一基礎,剩下的就是js交互了,整個過程瀏覽器就可以處理,而交換數據的文檔也不限於xml(現在常用json)。

ajax交互流程

一次ajax交互是瀏覽器向伺服器請求一次數據的過程,整個過程可分為4步:

  1. 請求發起:在此階段,由XMLHttpRequest發起一個http請求,GET、POST、PUT、DELETE、UPDATE等等都可以。
  2. 數據傳送:發起請求之後就要傳遞數據,不同的請求方式傳遞數據的方式細節不同,但都是瀏覽器向伺服器方向的,因為交互是雙方的,數據傳遞自然很重要。
  3. 監聽狀態:整個請求過程結束後瀏覽器的任務就是等,等待伺服器的響應,這個過程不會阻塞用戶,只是在後台監聽連接狀態,這裡就體現出非同步的優勢了。
  4. 接收響應:伺服器處理完數據之後,後返回結果給瀏覽器,瀏覽器就可以接收整個請求返回的響應信息,然後本次請求結束。

以上就是一次完整的ajax交互,下面來通過代碼展示一下簡單的ajax流程。

代碼演示

先來看代碼

var xhr = new XMLHttpRequest(); xhr.open(GET, url, true); // url 是一個URLxhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304){ // 獲得 xhr.responseText 為相應數據 }};xhr.send();

我們來一點點看其中涉及到的方法和相關概念,首先創建了一個XMLHttpRequest對象,然後接下來是一個open方法,第一個參數是請求方法,第二個參數是一個URL,默認情況要求同源(關於同源策略和跨域可以看我上一篇文章),第三個參數指的是是否為非同步請求,默認是true可以省略。open方法結束會初始化HTTP請求參數,但是並不發送請求。

做好請求發送準備了,不過現在還不能發送請求。因為請求是非同步的,我們無法獲知請求的進度和響應狀態,XMLHttpRequest給我們提供了一個事件onreadystatechange,我們可以通過監聽這個時間來關注這種變化,所以下一步是註冊onreadystatechange事件。

先了解一下readyState,當一個XMLHttpRequest初次創建時,這個readyState的值從0開始,直到接收到完整的HTTP響應,這個值增加到4,具體情況如下:

狀態| 名稱 | 描述

:-:|:-----------:|:--------------------------------------:

0 |Uninitialized| 初始化狀態。XMLHttpRequest 對象已創建或已被 abort() 方法重置。

1 |Open |open()方法已調用,但是 send() 方法未調用。請求還沒有被發送。

2 |Sent |Send()方法已調用,HTTP 請求已發送到 Web 伺服器。未接收到響應。

3 |Receiving |所有響應頭部都已經接收到。響應體開始接收但未完成。

4 |Loaded |HTTP 響應已經完全接收。

在這裡我們只要判斷這個值是不是4就可以知道響應是否接收完成了。

另一個要關注的就是status,它指的就是HTTP狀態碼,這個大家都很熟悉了,只要是200(OK)或304(Not Modified)就是成功的請求(這裡也可以關注statusText,它指的是狀態碼對應的名稱,不常用)。此時就可以獲取到響應數據了,responseText即為響應體內容(還有一個responseXML,它對請求的響應解析為XML並作為Document對象返回,不常用)。到此,請求準備完全完成。

接下來調用send方法,發送請求,其中如果是POST或PUT請求可以把請求體作為參數傳入。整個請求到此就發送完成了。

XMLHttpRequest還有幾個這裡沒涉及到的方法abort,getAllResponseHeaders,getResponseHeader,setRequestHeader,暫時用不到這裡不過多介紹了。

對於ie5、6,創建xhr對象要使用new ActiveXObject("Microsoft.XMLHTTP"),不過以後應該沒用了。

以上就是原生js實現的ajax,在實際開發中我們幾乎永遠都不會去寫ajax,封裝好的ajax庫有很多,比較熟悉的jquery中的$.ajax,$get,$post等等。到此,傳統的基於XMLHttpRequest 實現的ajax的內容就結束了,不過現在還有一個東西需要認識一下。

fetch

XMLHttpRequest的api上面已經看到了,可以說的上很複雜了,它複雜到我們平時幾乎都用不上原生api,於是,一種新的更優雅的解決方案--fetch誕生了。

首先fetch是新東西,先來看瀏覽器支持率:

可以看出其實不是很樂觀,不過不要緊,我們可以使用polyfill來實現,所以可以直接來看fetch的例子:

fetch(url, { method: GET, headers: new Headers({ Accept: application/json }) }).then(res=>{ return res.json() }).then(res=>{ console.log(res) }).catch(err=>{ // 處理異常 })

可以看出fetch是基於promise的(關於promise相關內容在這篇文章中提到過),所以可以鏈式調用,整個過程不難理解,請求結果如果是json還支持直接處理,fetch的api非常實用,適合現代前端開發使用,使用React開發時候通常我們都選fetch作為數據請求工具。


至此,這篇文章內容就結束了,最後還是版權信息:尊重原創,轉載分享前請先知悉作者,也歡迎指出錯誤不足共同交流,更多內容歡迎關注作者博客點擊這裡


推薦閱讀:

TCP/IP模型
【前端資訊】TypeScript 2.7 發布
奇舞周刊第 246 期: 無障礙設計 & 前端數據流哲學
前端優化實踐總結
前端指紋,尋找蛛絲馬跡(技術周刊 2018-02-23)

TAG:前端工程師 | 前端開發 | 前端入門 |