Fetch API 提供了一个 window.fetch()
接口来获取资源(包括网络资源)。Fetch API 可以用来替代 XMLHttpRequest ,可以在 Web Workers 中使用( WorkerGlobalScope.fetch()
)。
Fetch API 用法
语法:
1 | const fetchResponsePromise = fetch(resource [, init]) |
resource 参数
fetch()
方法接受一个必填参数 resource
,即要获取的资源(可以是一个字符类型的资源地址,包括 URL 对象,或者是一个 Request 对象)。它返回一个 Promise ,resolve 为对该请求的 Response ,只要服务器返回带 headers 响应——即使服务器响应的是 HTTP 错误状态(比如404 或 500)。如果遇到网络错误(比如权限或者其他问题)则会 reject 并传回 TypeError 。如果被中断,则会 reject 传回 AbortError。
fetch()
方法获取资源的权限由 内容安全策略(Content Security Policy) 的 connect-src 指令控制。
fetch()
的一般用法如下:
1 | fetch(url, { |
1 | async function getRequestData() { |
init 参数
fetch()
方法第二个参数为可选的 init
参数,作为请求的额外参数。
init 选项类似一个 Request 对象,你可以直接使用 Request 构造器创建一个 request。它包括以下选项:
1 | { |
Headers 对象
init 选项的 headers 可以是一个 Http headers 健值对,也可以为一个 Headers 对象。
Fetch API 的 Headers 接口允许对 HTTP 请求和响应头执行各种操作,出于安全考虑,某些 headers 字段 只能由用户代理(浏览器)控制,可以操作的 header 必须是 有效的 HTTP headers 字段。
一个 Headers 对象也有一个关联的 guard ,它具有不可变的值,request
,request-no-cors
,response
或 none
。
1 | const myHeaders = new Headers({ |
Response 对象
Fetch API 的 Response 接口呈现了对一次请求的响应数据。fetch()
方法在网络返回后会 resolve 一个 Response 对象。
Response 对象 有以下的属性和方法(Response 实现了 Body 接口,所以也可访问 Body 的属性和方法)
属性/方法 | 是否只读 | 含义 |
---|---|---|
Response.headers | 只读 | 包含此 Response 所关联的 Headers 对象。 |
Response.ok | 只读 | 包含了一个布尔值,标示该 Response 成功(HTTP 状态码的范围在 200-299)。 |
Response.redirected | 只读 | 表示该 Response 是否来自一个重定向,如果是的话,它的 URL 列表将会有多个条目。 |
Response.status | 只读 | 包含 Response 的状态码 (例如 200 表示成功)。 |
Response.statusText | 只读 | 包含了与该 Response 状态码一致的状态信息(例如,OK对应 200)。 |
Response.type | 只读 | 包含 Response 的类型(例如,basic、cors)。 |
Response.url | 只读 | 包含 Response 的URL。 |
Response.useFinalURL | 包含了一个布尔值,来标示这是否是该 Response 的最终 URL。 | |
Body.body | 只读 | 一个简单的 getter,用于暴露一个 ReadableStream 类型的 body 内容。 |
Body.bodyUsed | 只读 | 包含了一个布尔值来标示该 Response 是否读取过 Body。 |
Response.clone() | 创建一个 Response 对象的克隆。 | |
Response.error() | 返回一个绑定了网络错误的新的 Response 对象。 | |
Response.edirect() | 用另一个 URL 创建一个新的 Response。 | |
Body.arrayBuffer() | 读取 Response 对象并且将它设置为已读,并返回一个被解析为 ArrayBuffer 格式的 Promise 对象。 | |
Body.blob() | 读取 Response 对象并且将它设置为已读,并返回一个被解析为 Blob 格式的 Promise 对象。 | |
Body.formData() | 读取 Response 对象并且将它设置为已读,并返回一个被解析为 FormData 格式的 Promise 对象。 | |
Body.text() | 读取 Response 对象并且将它设置为已读,并返回一个被解析为 USVString 格式的 Promise 对象。 | |
Body.json() | 读取 Response 对象并且将它设置为已读,并返回一个被解析为 JSON 格式的 Promise 对象。 |
AbortController 阻止请求
fetch()请求发送以后,如果中途想要取消,需要使用 AbortController 对象。
1 | const controller = new AbortController(); |
与 XMLHttpRequest 差异
fetch()
使用 Promise,而 XMLHttpRequest 使用回调函数fetch()
采用模块化设计,API 分散在多个对象上(Response 对象、Request 对象、Headers 对象)fetch()
通过数据流(Stream 对象)处理数据,可以分块读取,有利于提高网站性能表现,减少内存占用,对于请求大文件或者网速慢的场景相当有用。XMLHttpRequest 对象不支持数据流,所有的数据必须放在缓存里,不支持分块读取,必须等待全部拿到后,再一次性访问
与 jQuery.ajax 差异
- 当接收到一个代表错误的 HTTP 状态码时,从
fetch()
返回的 Promise 不会被标记为 reject,即使响应的 HTTP 状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (如果响应的 HTTP 状态码不在 200 - 299 的范围内,则设置 resolve 返回值的 ok 属性为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。 fetch()
不会发送跨域 cookies,除非你使用了 credentials 的初始化选项。- 自2018 年 8 月以后,默认的 credentials 政策变更为 same-origin。Firefox 也在 61.0b13 版本中进行了修改。
- 如果你打算支持浏览器的旧版本,请确保在所有可能受 Cookie/用户 登录状态影响的api请求上包含
credentials: 'same-origin'
初始化选项。