Fetch 入門

1、什麼是Fetch ?

Fetch的定義

Fetch本質上是一種標準,該標準定義了請求、響應和綁定的流程。 Fetch標準還定義了Fetch () JavaScript API,它在至關低的抽象級別上公開了大部分網絡功能,咱們今天講的主要是Fetch API。Fetch API 提供了一個獲取資源的接口(包括跨域)。它相似於 XMLHttpRequest ,但新的API提供了更強大和靈活的功能集。 Fetch 的核心在於對 HTTP 接口的抽象,包括 Request,Response,Headers,Body,以及用於初始化異步請求的 global fetch。html

2、如何使用Fetch

fetch() 方法的使用

Fetch API 提供了一種全局fetch()方法,該方法位於 WorkerOrGlobalScope 這一個 mixin 中 方法用於發起獲取資源的請求。它返回一個 promise,這個 promise 會在請求響應後被 resolve,並傳回 Response 對象。git

fetch(input?: Request | string, init?: RequestInit): Promise<Response>

fetch(url, options).then(function(response) {
  // 處理 HTTP 響應
}, function(error) {
  // 處理網絡錯誤
})
複製代碼

fetch() 參數

fetch方法能夠接收兩個參數input和options。github

  • input 參數能夠是字符串,包含要獲取資源的 URL。也能夠是一個 Request 對象。json

  • options 是一個可選參數。一個配置項對象,包括全部對請求的設置。可選的參數有:api

method: 請求使用的方法,如 GET、POST。
headers: 請求的頭信息,包含與請求關聯的Headers對象。
body: 請求的 body 信息。注意 GET 或 HEAD 方法的請求不能包含 body 信息
mode: 請求的模式,如 cors、 no-cors 或者 same-origin。
credentials: 請求的 credentials,如 omit、same-origin 或者 include。爲了在當前域名內自動發送 cookie , 必須提供這個選項。跨域

經常使用的fetch請求

HTML

fetch('/index/fetchHtml')
  .then((res) => {
    return res.text()
  }).then((result) => {
    document.body.innerHTML += result
  })
  .catch((err) => {
  })
複製代碼

JSON

fetch('/api/user/CaiCai')
  .then((res) => {
    return res.json()
  })
  .then((json) => {
    console.log(json)
  })
  .catch((err => {
  }))

複製代碼

POST Form

function postForm() {
  const form = document.querySelector('form')
  const name = encodeURI(document.getElementsByName('name')[0].value)
  fetch(`/api/user/${name}`, {
    method: 'POST',
    body: new FormData(form)
  })
}
複製代碼

POST JSON

fetch('/api/user/CaiCai', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'CaiCai',
    age: '26',
  })
})

複製代碼

fetch注意事項

1. 錯誤處理

fetch只有在網絡錯誤的狀況,返回的promise會被reject。成功的 fetch() 檢查不只要包括 promise 被 resolve,還要包括 Response.ok 屬性爲 true。HTTP 404 狀態並不被認爲是網絡錯誤,因此Promise的狀態爲resolve。promise

2. credentials 設置

fetch能夠經過credentials本身控制發送請求時是否帶上cookie。credentials可設置爲include、same-origin、omit。include爲了讓瀏覽器發送包含憑據的請求(即便是跨域源)。若是你只想在請求URL與調用腳本位於同一塊兒源處時發送憑據,請添加credentials: 'same-origin'。要改成確保瀏覽器不在請求中包含憑據,請使用credentials: 'omit'。瀏覽器

credentials 默認是「same-origin」,可是如下版本的瀏覽器實現了一個更老版本的fetch規範,其中默認是「忽略」: Firefox 39-60 Chrome 42 - 67 Safari 10.1 11.1.2 若是您的目標是這些瀏覽器,建議始終對全部fetch請求顯式指定憑據:'同源',而不是依賴於默認緩存

3. 停止

fetch 自身並無提供 停止請求的方法。可是部分瀏覽器有實現AbortController,能夠經過AbortController停止fetch請求bash

const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => controller.abort(), 5000);


fetch('/api/user/CaiCai', {
  signal, // 在option中加入signal
  method: 'POST',
  // credentials:'include',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'CaiCai',
    age: '26',
  })
}).then((res) => {
  return res.json()
}).then((result) => {
  console.log(result)
}).catch((err) => {
  console.log(err)
})

複製代碼

4.兼容性

如下Can I Use上顯示的,是fetch的兼容性狀況,目前已經支持大部分瀏覽器,不支持的瀏覽器可使用fetch polyfill

3、爲何要用Fetch、而不用XHR

一、fetch返回的是promise對象,比XMLHttpRequest的實現更簡潔,fetch 使用起來更簡潔 ,完成工做所需的實際代碼量也更少
二、fetch 可自定義是否攜帶Cookie
三、fetch在ServiceWorker中使用,至於ServiceWorker能有什麼優點,會在將來寫ServiceWorker的時候回寫到

4、爲何放棄fetch

首先,謝謝各位同窗的指出文章的中問題,標題確實欠妥,文不對題。這裏補充下fetch的一些問題:
1.fetch不支持jsonp,若是項目中使用到JSONP,須要單獨實現一個JSONP。
2.fetch自身並無提供abort的方法,須要AbortController去處理停止,實現起來會繁瑣一點。而且AbortController兼容性不是很好,不過@周公來同窗指出,咱們可使用「abortcontroller-polyfill」。
3.在咱們日常使用中,fetch相對XHR差異不大,而且就像@jokerapi同窗說的「實際業務上,api 請求都是用再次封裝好的函數來處理的。底層是 Fetch 仍是 XHR 影響不大。」。因此若是沒有特別的需求,從XHR升級到fetch的意義不大。可是在ServiceWorker中fetch會大放異彩。目前淘寶首頁就使用fetch+ServiceWorker來實現離線緩存。

參考連接:

Fetch API
開始學習Fetch
淺談 Fetch
fetch polyfill

相關文章
相關標籤/搜索