原文連接 轉自:http://www.brucezhou.com/2017/01/11/深刻淺出Fetch-API/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const url = URL.format({
pathname: '/api/add',
});
/* URL是url模塊,能夠很方便的處理url,提供了兩個方法: format、parse
* format: 將對象變成字符串,parse: 將字符串變成對象
* 類似的一個模塊叫querystring,專門處理查詢字符串,也提供了兩個方法: stringify、parse
**/
const headers = new Headers({
`Content-Type`: "application/json"
});
const request = new Request(url, {
method: 'POST',
mode: 'cors',
// 該屬性決定了是否能夠跨域,但成功與否還要看服務器的支持
credentials: 'include',
// 該屬性決定了請求是能夠否帶cookie
headers,
body: JSON.stringify(body),
// body不能是一個對象
});
const response = await fetch(request);
const body = await response.json();

Fetch引入了3個接口: Headers, Request, Response,它們直接對應HTTP中的相應概念,下面將依次介紹。git

Headers

經常使用方法

Headers接口是一個簡單的鍵值對,Request接口中的headers參數就能夠直接用一個對象來代替,但它和普通對象的不一樣在於它提供瞭如下一些方法,且大多方法的返回值是能夠被for of迭代的,使得操做Header更爲方便 Headers接口的方法Headers接口的方法github

guard屬性

在Headers對象中有一個guard 屬性,來指定其是否能夠被改變,其有如下5種取值。編程

  • none:默認值
  • request:Request.headers 對象只讀
  • request-no-cors:在 no-cors 模式下,Request.headers 對象只讀
  • response:Response.headers 對象只讀
  • immutable:一般在 ServiceWorkers 中使用,全部 Header 對象都爲只讀

Request

其有兩個參數,第一個參數是URL(字符串),其餘參數都經過第二個參數(對象)傳遞,下面將詳細說明第二個參數中的相應字段。json

mode

mode參數用來決定是否容許跨域請求,以及哪些response屬性可讀。可選的mode值爲 same-originno-cors(默認)以及 corsapi

  • same-origin: 請求遵照同源策略
  • cors: 請求遵照CORS協議,並只有有限的一些 Header 被暴露給 Response 對象,可是 body 是可讀的,雖然容許跨域,但成功與否,還要看服務器支持,在服務器上能夠設置Access-Control-Allow-Origin頭,容許全部的話,能夠設置爲*
  • no-cors: 該模式容許來自 CDN 的腳本、其餘域的圖片和其餘一些跨域資源,可是首先有個前提條件,就是請求的 method 只能是HEAD、GET 或 POST,另外JS不能訪問 Response 對象中的任何屬性。

credentials

該屬性與XHR中的withCredentials相同,決定了是否能夠跨域訪問cookie,可是有三個值:omit(默認), same-origininclude.
好比你要跨域訪問一個服務器,並要攜帶cookie,那就要把這個屬性設置爲include跨域

官方文檔關於Request的介紹很詳細緩存

Response

Response 對象一般在 fetch() 的回調中得到,也能夠經過 JS 構造,不過這一般只在 ServiceWorkers 中使用。
其經常使用屬性有statusstatusTextheaderstypebody,下面分別介紹。
statusstatusTextheaders和HTTP保持一致。服務器

type

type屬性的值可能有: basiccorsdefaultopaquecookie

  • basic:同域的響應,除 Set-Cookie 和 Set-Cookie2 以外的全部 Header 可用
  • cors:Response 從一個合法的跨域請求得到,某些 Header 和 body 可讀
  • error:網絡錯誤。Response 對象的 status 屬性爲 0,headers 屬性爲空而且不可寫。當 Response 對象從 Response.error() 中獲得時,就是這種類型
  • opaque:在 no-cors 模式下請求了跨域資源。依靠服務端來作限制

body

body的類型只能是如下幾種的一個網絡

  • ArrayBuffer
  • ArrayBufferView
  • Blod/File
  • string
  • URLSearchParams
  • FormData

注意並無對象,這意味着若是要傳一個對象的話,必須先把它stringify,而後把Content-Type設置爲application/json

Fetch還針對以上類型提供了對應的方法,將body從Request或Response中取出來,這些方法都返回一個使用實際內容 resolve 的 Promise 對象。

  • arrayBuffer()
  • blod()
  • json()
  • text()
  • formData()

body只能被讀取一次

很是重要的一點是,Request 和 Response 的 body 只能被讀取一次!它們有一個屬性叫 bodyUsed,讀取一次以後設置爲 true,以後就不能再被讀取了。
這樣設計的目的是爲了以後兼容基於流的 API,咱們的目的是當數據到達時就進行相應的處理,這樣就使得 JavaScript 能夠處理大文件例如視頻,而且能夠支持實時壓縮和編輯。
那麼,如何讓 body 能被屢次讀取呢?API 爲這兩個對象提供了一個 clone() 方法。調用這個方法能夠獲得一個克隆對象,對象中包含全新的 body。不過要記得,clone() 必需要在使用 body 以前調用,也就是先 clone() 再讀使用。

serviceWorker

在 Fetch 規範中對 API 進行了定義,它結合 ServiceWorkers,嘗試作到以下優化:改善離線體驗,保持可擴展性。
serviceWorker做爲一個新的API,能夠攔截HTTP請求,經過編程的方式去控制HTTP緩存,還能夠作到提早加載,加快首屏渲染速度。

參考資料

fetch API 簡介
官方文檔
fetch polyfill