前端|淺談fetch

Fetch.png

Why Fetch

在開發過程中,我們向服務端發送請求,一般會使用三種方式, XMLHttpRequest(XHR),Fetch ,jQuery實現的AJAX。
其中, XMLHttpRequest(XHR)和Fetch是瀏覽器的原生API,jquery的ajax其實是封裝了XHR。
讓我們首先來比較一下這三者的使用示例。

XMLHttpRequest

var xhr;
if (window.XMLHttpRequest) {  // Mozilla, Safari...
   xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
   try {
     xhr = new ActiveXObject('Msxml2.XMLHTTP');
   } catch (e) {
     try {
       xhr = new ActiveXObject('Microsoft.XMLHTTP');
     } catch (e) {}
   }
}
if (xhr) {
   xhr.onreadystatechange = onReadyStateChange;
   xhr.open('POST', '/api', true);
   // 設置 Content-Type 為 application/x-www-form-urlencoded
   // 以表單的形式傳遞數據
   xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   xhr.send('username=admin&password=root');
}

// onreadystatechange 方法
function onReadyStateChange() {
   // 該函數會被調用四次
   console.log(xhr.readyState);
   if (xhr.readyState === 4) {
      // everything is good, the response is received
      if (xhr.status === 200) {
         console.log(xhr.responseText);
      } else {
         console.log('There was a problem with the request.');
      }
   } else {
      // still not ready
      console.log('still not ready...');
   }
}

從上邊的代碼可以看出,XMLHttpRequest 是一個非常粗糙的API,不符合關注分離(Separation of Concerns)的原則,配置和調用方式非常混亂,前端程序員們不僅要做各個瀏覽器的兼容性,還飽受回調地獄的折磨,這顯然不是一個好的選擇。

jQuery實現AJAX

$.ajax({
    method: 'POST',
    url: '/api',
    data: { username: 'admin', password: 'root' }
})
  .done(function(msg) {
      alert( 'Data Saved: ' + msg );
  });

jQuery作為一個使用人數最多的庫,其AJAX很好的封裝了原生AJAX的代碼,在兼容性和易用性方面都做了很大的提高,而且jQuery還把jsonp裝在了AJAX里面,這樣我們就可以開心的跨域了!!!!對比原生AJAX的實現,使用jQuery實現的AJAX就異常簡單了.
但是,筆鋒一轉,我們仍然逃脫不了一個問題,回調地獄。。。。

Fetch

fetch(...).then(fun2)
          .then(fun3) //各依賴有序執行
          .....
          .catch(fun)

從上邊的代碼可以看出,fetch用起來想jQuery一樣簡單,雖然還是有Callback的影子,但是看起來舒服多了


詳解Fetch API

兼容性

注意:由于Fetch API是基于Promise設計,舊瀏覽器不支持Promise,需要使用pollyfill es6-promise

  1. Fetch使用說明
fetch(url, options).then(function(response) { 
// handle HTTP response
}, function(error) {
 // handle network error
})

說明:
a. fetch api返回的是一個promise對象
b.Options:

  • method(String): HTTP請求方法,默認為GET
  • body(String): HTTP的請求參數
  • headers(Object): HTTP的請求頭,默認為{}
  • credentials(String): 默認為omit,忽略的意思,也就是不帶cookie;還有兩個參數,same-origin,意思就是同源請求帶cookie;include,表示無論跨域還是同源請求都會帶cookie

c.第一個then函數里面處理的是response的格式,這里的response具體如下:


image.png
  • status(number): HTTP返回的狀態碼,范圍在100-599之間
  • statusText(String): 服務器返回的狀態文字描述,例如Unauthorized,上圖中返回的是Ok
  • ok(Boolean): 如果狀態碼是以2開頭的,則為true
  • headers: HTTP請求返回頭
  • body: 返回體,這里有處理返回體的一些方法
    • text(): 將返回體處理成字符串類型
    • json(): 返回結果和 JSON.parse(responseText)一樣
    • blob(): 返回一個Blob,Blob對象是一個不可更改的類文件的二進制數據
    • arrayBuffer()
    • formData()
  1. Fetch常見坑
  • 兼容性
image.png

如caniuse所示,IE瀏覽器完全不支持fetch,移動端的很多瀏覽器也不支持,所以,如果要在這些瀏覽器上使用Fetch,就必須使用fetch polyfill

  • cookie傳遞
    必須在header參數里面加上credentials: 'include',才會如xhr一樣將當前cookies帶到請求中去
  • fetch和xhr的不同
    fetch雖然底層,但是還是缺少一些常用xhr有的方法,比如能夠取消請求(abort)方法
    fetch在服務器返回4xx、5xx時是不會拋出錯誤的,這里需要手動通過,通過response中的ok字段和status字段來判斷
  1. 實踐總結
    我們在實際應用中雖然會因為它沒有interceptor等原因還需要再封裝一層,但fetch api仍然不失為一個非常贊的API。。。。

4.參考

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 本文詳細介紹了 XMLHttpRequest 相關知識,涉及內容: AJAX、XMLHTTP、XMLHttpReq...
    semlinker閱讀 13,710評論 2 18
  • 原諒我做一次標題黨,Ajax 不會死,傳統 Ajax 指的是 XMLHttpRequest(XHR),未來現在已被...
    9a9Hbx閱讀 15,025評論 17 161
  • 本博客轉自:「作者:若愚鏈接:https://zhuanlan.zhihu.com/p/22361337來源:知乎...
    韓寶億閱讀 2,786評論 0 3
  • 原諒我做一次標題黨,Ajax 不會死,傳統 Ajax 指的是 XMLHttpRequest(XHR),未來現在已被...
    茶藝瑤閱讀 1,331評論 0 4
  • 老公特別不喜歡我把時間用在翻看朋友圈上,但是我覺得其實并不是毫無收獲,反而,就今兒看到的朋友圈,讓我感受頗多。 時...
    凡佳人閱讀 274評論 0 0