前端|淺談fetch

Fetch.png

Why Fetch

在開發(fā)過程中,我們向服務(wù)端發(fā)送請(qǐng)求,一般會(huì)使用三種方式, XMLHttpRequest(XHR),F(xiàn)etch ,jQuery實(shí)現(xiàn)的AJAX。
其中, XMLHttpRequest(XHR)和Fetch是瀏覽器的原生API,jquery的ajax其實(shí)是封裝了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);
   // 設(shè)置 Content-Type 為 application/x-www-form-urlencoded
   // 以表單的形式傳遞數(shù)據(jù)
   xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   xhr.send('username=admin&password=root');
}

// onreadystatechange 方法
function onReadyStateChange() {
   // 該函數(shù)會(huì)被調(diào)用四次
   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 是一個(gè)非常粗糙的API,不符合關(guān)注分離(Separation of Concerns)的原則,配置和調(diào)用方式非?;靵y,前端程序員們不僅要做各個(gè)瀏覽器的兼容性,還飽受回調(diào)地獄的折磨,這顯然不是一個(gè)好的選擇。

jQuery實(shí)現(xiàn)AJAX

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

jQuery作為一個(gè)使用人數(shù)最多的庫(kù),其AJAX很好的封裝了原生AJAX的代碼,在兼容性和易用性方面都做了很大的提高,而且jQuery還把jsonp裝在了AJAX里面,這樣我們就可以開心的跨域了?。。?!對(duì)比原生AJAX的實(shí)現(xiàn),使用jQuery實(shí)現(xiàn)的AJAX就異常簡(jiǎn)單了.
但是,筆鋒一轉(zhuǎn),我們?nèi)匀惶用摬涣艘粋€(gè)問題,回調(diào)地獄。。。。

Fetch

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

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


詳解Fetch API

兼容性

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

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

說明:
a. fetch api返回的是一個(gè)promise對(duì)象
b.Options:

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

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


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

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

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

4.參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容