原文连接 转自: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