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