前言
在 WEB 中,对于网络请求一直使用的是 XMLHttpRequest API 来处理,XMLHttpRequest 也很强大,传统的 Ajax 也是基于此 API 的。那么为什么 W3C 标准中又加入了类似功能的 Fetch API 呢?他有何优势。
Fetch
什么是 Fetch
Fetch 提供了 Request 和 Response 对象的通用定义(以及与网络请求有关的其他内容)。这将允许 Fetch 在将来需要的任何地方使用,无论在 serviceWorker、Cache API以及处理或修改 Request 和 Response 的其他类似事物上,或者任何可能需要你以编程方式生成的 Response 的地方。
它还提供了相关概念的定义,例如 CORS 和 HTTP 原始头语义,在其他地方取代它们的单独定义。
要发出请求并获取资源,请使用 WindowOrWorkerGlobalScope.fetch() 方法。这使得它几乎可以在你想要获取资源的任何上下文中使用。
Fetch API 是 W3C 正式规范中加入的新的用于网络请求相关的功能 API,核心就是对于 HTTP 接口的抽象,包含 Request / Response / Headers / Body,通过这些抽象出来的模块,对于 HTTP 相关的操作变得更简单方便。Fetch API 是异步化的接口,所有的结果都是 Promise 化的,同样在 window 环境和 seviceWorker 环境下均可访问。在 ServiceWorker 中,Fetch 被大量使用。
对于使用过 XMLHttpRequest 的人来说,很容易上手。但 Fetch API 功能更强大和灵活。
模块与 fetch 的关系
![](https://img-blog.csdnimg.cn/20190427103213293.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9sZXBpbmcuYmxvZy5jc2RuLm5ldA==,size_16,color_FFFFFF,t_70)
接口
描述 Fetch 的接口,不是很单纯,它是以抽象出来的 HTTP 的那些模块来组合的。下面简单列一下,后面每个模块详细说明。
fetch
位于 WindowOrWorkerGlobalScope 这一个 mixin 中的 fetch() 方法用于发起获取资源的请求。它返回一个 promise,这个 promise 会在请求响应后被 resolve,并传回 Response 对象。
Window 和 WorkerGlobalScope 下均可访问 fetch() 方法。
fetch() 方法由 Content Security Policy 的 connect-src指令控制,而不是它请求的资源。
HTTP 404 状态并不被认为是网络错误。
语法
Promise<Response> fetch(input[, init]);
fetch() 的构造器和 Request 的构造器完全一样。
参数
resource
:支持以下两种类型:
USVString
:要获取资源的 URL 字符串。(有些浏览器也支持blob:
和data:
类型的 URL)Request
对象。 (Request 这块在后面 Request 部分说)
init
:可选。可设置任何需要应用到 Request 中的配置项。通常设置如下:
method
:请求的方法。如POST
、GET
等。注意在 Fetch 请求方法为 GET 或 HEAD 下不能设置 Origin 头。(Firefox 65 已修正此问题 - 参考:Bug1508661)headers
:在 Headers 对象或具有 ByteString 值的对象中的任何你想添加的头。注意某此名称是被禁止的。body
:任何你想添加到 Request 中的 body,它可以是 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或者 HEAD 方法的 Request 没有 body。mode
:用于请求的模式。例如:cors
,no-cors
, 或者same-origin
。credentials
:用于请求的受信类型,包括:omit
,same-origin
, 或者include
。要自动发送当前域的cookie,必须提供此选项。从Chrome 50开始,此属性还会使用FederatedCredential实例或PasswordCredential实例。cache
:要用于请求的缓存模式。redirect
:要使用的重定向模式:follow
(自动跟随重定向),error
(如果发生重定向则中止错误),manual
(手动处理重定向)。Chrome 默认follow
(Chrome 47 以前默认manual
)。referrer
:指定no-referrer
,client
或URL
的USVString
。默认为client
。referrerPolicy
:指定 referer HTTP 标头的值。 可以是no-referrer
,no-referrer-when-downgrade
,origin
,origin-when-cross-origin
,unsafe-url
。integrity
:包含请求的子资源完整性值(例如:sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=)。keepalive
:keepalive
选项可用于允许请求比页面长。带keepalive
标志的 fetch 替代了navigator.sendboacon() API。signal
:AbortSignal实例。允许你与获取请求进行通信,并在需要时通过AbortController中止它。
返回值
Promise,resolve 时回传 Response 对象。
例外
类型 | 描述 |
---|---|
AbortError | 请求中断 (通过使用 AbortController.abort()) |
TypeError | 从Firefox 43开始,如果 URL 包含 credentials ,则 fetch() 将抛出 TypeError,例如 http:// user:[email protected]。 |
Request
Fetch API 的 Request 接口表示资源请求。
你可以使用 Request.Request()
构造函数创建新的 Request 对象,你也可以通过一个 API 操作返回 Request 对象,例如 serviceWorker 中的 FetchEvent.request。
构造器
Request.Request()
创建新的 Request 对象。
语法
var myRequest = new Request(input[, init]);
参数
input: 可用如下之一:
- 要获取资源的 URL 字符串。
- Request 对象,用于创建副本。请注意以下行为更新以保持安全性,同时使构造函数不太可能抛出异常:
- 如果此对象存在于构造函数调用的另一个源上,则会剥离 Request.referrer。
- 如果此对象具有
navigate
的 Request.mode,则mode
值将转换为same-origin
。
init: 可选。同 fetch init。
属性
- cache:包含请求的缓存模式,例如:
default
,reload
,no-cache
。 - credentials:包含请求的凭据,例如:
omit
,same-origin
,include
。默认same-origin
。 - destination:返回RequestDestination枚举中的字符串,描述请求的目标。这是一个字符串,表示所请求内容的类型。
- headers:包含请求的关联 Headers 对象。
- integrity:包含请求的子资源完整性值。例如:
sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=
。 - method:包含请求的方法,GET/POST等。
- mode:包含请求的模式。例如:
cors
,no-cors
,same-origin
,navigate
。 - redirect:包含重定向处理方式。它可能是其中之一:
follow
,error
,manual
。 - referrer:包含请求的引用者。例如:
client
。 - referrerPolicy:包含请求的引用者策略。例如:
no-referrer
。 - url:包含请求中的 URL。
- bodyUsed :存储一个布尔值,声明是否已在响应中使用过。
Request 实现 Body,所以 Body 的属性和方法在 Request 中依然有效。关于 Body,后面说。
Headers
Fetch API 的 Headers 接口允许你对 HTTP 请求和响应头执行各种操作。这些操作包括检索,设置,添加和删除。Headers 对象具有关联的标题列表,该列表最初为空,由零个或多个名称和值对组成。在此接口的所有方法中,标头名称由不区分大小写的字节序列匹配。
出于安全原因,某些标头只能由浏览器控制。这些标头包括禁止的标头名称和禁止的响应标头名称。
一个Headers对象也有一个相关的“门”,取值为immutable
, request
, request-no-cors
, response
, none
。它会影响 set()
, delete()
, append()
是否会改变 header。
你也可以通过 Request.headers 和 Response.headers 属性取 Headers 对象。
构造器
Headers
创建一个 Header 对象。
语法:
var myHeaders = new Headers(init);
参数:
- init:包含要使用其预填充 Headers 对象的任何HTTP标头的对象。这可以是具有 ByteString 值的简单对象值或现有的 Headers 对象(新的 Headers 对象从现有的Headers对象继承其数据)。
方法
append(name, value)
:将新值附加到 Headers 对象内的现有标头上,或者如果标头、不存在则添加标头。此方法用于一个属性对应多个值的添加方法。delete(name)
:方法从当前 Headers 对象中删除指定标头。entries()
:方法返回一个迭代器,允许遍历此对象中包含的所有键/值对。每对的键和值都是 ByteString 对象。forEach()
:为每个数组元素执行一次提供的函数。get(name)
:方法返回具有给定名称的 Headers 对象中标头的所有值的字节字符串。如果 Headers 对象中不存在请求的标头,则返回 null。has(name)
:方法返回一个布尔值,表明Headers对象是否包含某个头。keys()
:方法返回一个迭代器,允许遍历此对象中包含的所有键。键是 ByteString 对象。set(name, value)
:方法为 Headers 对象内的现有标头设置新值,或者如果标头尚不存在则添加标头。(set 和 append 之间的区别在于,如果指定的头已经存在并接受多个值,则 set 将使用新值覆盖现有值,而 append将新值附加到值集的末尾)values()
:返回一个迭代器,允许遍历此对象中包含的所有值。值是 ByteString 对象。
如果在 Header 中的方法中使用不在可用 HTTP 标头中的值,则会抛出 TypeError 错误。
可用 HTTP 表头
表头根据上下文有如下几类:
- 常规标题:标题适用于请求和响应,但与最终在正文中传输的数据无关。
- 请求标头:包含有关要提取的资源或客户端本身的更多信息的标头。
- 响应标头:包含有关响应的其他信息的标头,例如其位置或服务器本身(名称和版本等)。
- 实体标头:包含有关实体主体的更多信息的标头,例如其内容长度或MIME类型。
认证类:
- WWW-Authenticate
- Authorization
- Proxy-Authenticate
- Proxy-Authorization
缓存类:
- Age
- Cache-Control
- Clear-Site-Data
- Expires
- Pragma
- Warning
客户端提示类:
- Accept-CH
- Accept-CH-Lifetime
- Early-Data
- Content-DPR
- DPR
- Save-Data
- Viewport-Width
- Width
条件类:
- Last-Modified
- ETag
- If-Match
- If-None-Match
- If-Modified-Since
- If-Unmodified-Since
- Vary
连接管理类:
- Connection
- Keep-Alive
内容判断类:
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
控制类:
- Expect
- Max-Forwards
Cookie 类:
- Cookie
- Set-Cookie
CORS 类:
- Access-Control-Allow-Origin
- Access-Control-Allow-Credentials
- Access-Control-Allow-Headers
- Access-Control-Allow-Methods
- Access-Control-Expose-Headers
- Access-Control-Max-Age
- Access-Control-Request-Headers
- Access-Control-Request-Method
- Origin
- Timing-Allow-Origin
- X-Permitted-Cross-Domain-Policies
不追踪类:
- DNT
- TK
下载类:
- Content-Disposition
消息正文类:
- Content-Length
- Content-Type
- Content-Encoding
- Content-Language
- Content-Location
代理类:
- Forwarded
- X-Forwarded-For
- X-Forwarded-Host
- X-Forwarded-Proto
- Via
重定向类:
- Location
请求上下文类:
- From
- Host
- Referer
- Referrer-Policy
- User-Agent
响应上下文类:
- Allow
- Server
范围请求类:
- Accept-Ranges
- Range
- If-Range
- Content-Range
安全类:
- Cross-Origin-Resource-Policy
- Content-Security-Policy
- Content-Security-Policy-Report-Only
- Expect-CT
- Feature-Policy
- Public-Key-Pins
- Public-Key-Pins-Report-Only
- Strict-Transport-Security
- Upgrade-Insecure-Requests
- X-Content-Type-Options
- X-Download-Options
- X-Frame-Options
- X-Powered-By
- X-XSS-Protection
服务器发送事件类:
- Last-Event-ID
- NEL
- Ping-From
- Ping-To
- Report-To
转移编码类:
- Transfer-Encoding
- TE
- Trailer
WebSockets 类:
- Sec-WebSocket-Key
- Sec-WebSocket-Extensions
- Sec-WebSocket-Accept
- Sec-WebSocket-Protocol
- Sec-WebSocket-Version
其他:
- Accept-Push-Policy
- Accept-Signature
- Alt-Svc
- Date
- Large-Allocation
- Link
- Push-Policy
- Retry-After
- Signature
- Signed-Headers
- Server-Timing
- SourceMap
- Upgrade
- X-DNS-Prefetch-Control
- X-Firefox-Spdy
- X-Pingback
- X-Requested-With
- X-Robots-Tag
- X-UA-Compatible
Response
Response 接口表示请求的响应。
构造器
Response()
语法:
var myResponse = new Response(body, init);
参数:
body:(可选)
定义响应主体的对象。这可以是null,或者是:
- Blob
- BufferSource
- FormData
- ReadableStream
- URLSearchParams
- USVString
init:(可选)
包含要应用于响应的任何自定义设置的选项对象。可选:
- status:响应的状态代码,例如:
200
。 - statusText:与状态代码关联的状态消息,例如,
OK
。 - headers:要添加到响应的任何标头,包含在 Headers 对象或 ByteString 键/值对的对象文本。(可参考 HTTP Headers)
属性
- headers:接口的头只读属性包含与响应关联的 Headers 对象。
- ok:接口的 ok 只读属性包含一个布尔值,表明响应是否成功(状态在200-299范围内)
- redirected :属性指示响应是否是您重定向的请求的结果。依靠 redirected 来过滤掉重定向,可以轻松进行伪造重定向,以防止你的内容按预期工作。相反,你应该在调用 fetch() 时执行过滤。
- status:响应的状态代码。
- statusText:相应状态文字。
- type:响应类型:
- basic:正常情况下同域响应,除
Set-Cookie
和Set-Cookie2
外,所有标题都被暴露。 - cors:从有效的跨源请求收到响应。
- error:网络错误。 没有描述错误的有用信息。响应的状态为 0,标头为空且不可变。 这是从
Response.error()
获取的响应的类型。 - opaque:响应“no-cors”请求到跨源资源。
- opaqueredirect:获取请求是使用重定向
manual
进行的。 响应的状态为 0,标题为空,正文为空。
- basic:正常情况下同域响应,除
- url:包含响应的 URL。 url 属性的值将是重定向后获得的最终 URL。
- bodyUsed :布尔值,声明是否已在响应中使用了正文。
方法
- clone():方法创建响应对象的克隆,在各方面都相同,但存储在不同的变量中。
- error():方法返回与网络错误关联的新Response对象。
- redirect(url, status):方法返回一个 Response,导致重定向到指定的 URL。
Request 实现 Body,所以 Body 的属性和方法在 Request 中依然有效。关于 Body,后面说。
Body
Body 表示响应 / 请求的主体,允许你声明其内容类型以及应如何处理它。
Body 由 Request 和 Response 实现。这为这些对象提供了关联的主体(流),使用过的标志(最初未设置)和MIME类型(最初是空字节序列)。
属性
- body:是一个简单的getter,用于公开body内容的ReadableStream。
- bodyUsed:布尔值,指示是否已读取 body。
方法
- arrayBuffer():方法接受一个 Response 流并将其读取完成。它返回一个使用 ArrayBuffer 解析的 promise。
- blob():方法接受一个 Response 流并将其读取完成。它返回一个用 Blob 解析的 promise。(注意 如果 Response 的 Response.type 为
opaque
,则生成的 Blob 将具有 0 的 Blob.size 和空字符串“”
的 Blob.type,这使得它对 URL.createObjectURL 等方法无效。) - formData():方法接受一个 Response 流并将其读取完成。它返回一个使用 FormData 对象解析的 promise。(这主要与 serviceWorker 有关。 如果用户提交表单并且 serviceWorker 截获请求,你可以在其上调用
formData()
以获取键值映射,修改某些字段,然后将表单向前发送到服务器) - json():方法接受一个 Response 流并将其读取完成。它返回一个 promise,它以将正文解析为 JSON 的结果解析。
- text(): 方法接受一个 Response 流并将其读取完成。 它返回一个使用 USVString 对象(文本)解析的 promise。 始终使用 UTF-8 解码响应。
浏览器兼容性
博客名称:王乐平博客
CSDN博客地址:http://blog.csdn.net/lecepin
![知识共享许可协议](https://img.alicdn.com/tfs/TB1KZKfRCzqK1RjSZFHXXb3CpXa-88-31.png)