能执行 XMLHTTPRequest 对象的所有任务
Fetch API 必须是异步 (XHR 可以选择异步或同步)

Fetch API 本身使用 JavaScript 请求资源的优秀工具,同时 这个 API 也能够应用在 service worker 中,提供拦截、 重定向和修改通过 fetch() 生成的请求接口

基本用法

fetch() 方法在全局作用域中,调用后浏览器向给定 URL 发送请求

  • 主页面执行线程
  • 模块
  • service worker

    1. let r = fetch('/bar');
    2. console.log(r); // Promise <pending>

    URL 的格式 (相对路径、绝对路径等)的解释与 XHR 对象一样
    请求完成并且资源可用时,Promise 会解决为一个 Response 对象。

  • 是 API 的封装

  • 读取响应

    • text() 文本格式
    • json() JSON 格式
      1. fetch('bar.txt')
      2. .then((response) => {
      3. response.text().then((data) => {
      4. console.log(data);
      5. });
      6. });
  • status 状态码

  • statusText 状态文本

    自定义选项

    只使用 URL ,fetch() 只会发送 GET 请求,含最低限度的请求头。由每二个参数 init 对象作进一步的配置如何发送请求

  • body 指定使用请求体时请求体的内容

    • Blob、BufferSource、FormData、URLSearchParams、ReadableStream 或 String 的实例
  • cache 浏览器与 HTTP 缓存交,redirect 属性值必须 “follow”,必须符合同源策略
    • default 默认值
      • fetch() 返回命中有效缓存 ,不发送请求
      • 命中无效缓存会发送条件 式请求。如果响应已经改变,则更新缓存的值。然后 fetch() 返回缓存的值
      • 未命中缓存会发送请求,并缓存响应。然后 fetch() 响应
    • no-store
      • 浏览器不检查缓存,直接发送请求
      • 不缓存响应,直接通过 fetch() 返回
    • reload
      • 浏览器不检查缓存,直接发送请求
      • 缓存响应,再通过 fetch() 返回
    • no-cache
      • 无论命中有效缓存还是无效缓存都会发送条件式请求。如果响应已经改变,则更新缓存的值。然后 fetch() 返回缓存的值
      • 未命中缓存 会发送请求,并缓存响应。然后 fetch() 返回响应
    • force-cache
      • 无论命中有效缓存还是无效缓存都通过 fetch() 返回。不发送请求。
      • 未命中缓存会发送请求,并缓存响应。然后 fetch() 返回响应
    • only-if-cached
      • 只在请求模式为 same-origin 时使用缓存
      • 无论命中有效缓存还是无效缓存都通过 fetch() 返回。不发送请求
      • 未命中缓存返回状态码为 504 网关超时的响应
  • credentials 指定在外发请求中如何包含 cookie
    • omit 不发送 cookie
    • same-origin(默认值) 只在同源时发送
    • include 无论同源还是跨域都包含 cookies
  • headers 指定请求头部
    必须是 Headers 对象实例或包含字符串格式键/值对的常规对象
    默认值为不包含键/值对的 Headers 对象。这不意味着请求不包含任何头部,浏览器仍然会随请求
    发送一些头部。虽然这些头部对 JavaScript 不可见,但浏览器的网络检查器可以观察到
  • integrity 强制子资源完整性 必须是包含子资源完整性标识符的字符串,默认值是 ‘’
  • keepalive 指示浏览器允许请求存在时间超出页面生命周期。默认值为 false
  • method 用于指定 HTTP 请求方法
    • GET 默认值
    • POST
    • PUT
    • PATCH
    • DELETE
    • OPTIONS
    • CONNECT
    • TRACE
  • mode 请求模式

    • cors 允许遵守 CORS 协议的跨源请求。响应是“CORS 过滤的响应”,意思是响应中可以访问 的浏览器头部是经过浏览器强制白名单过滤的
    • no-cors 允许不需要发送预检请求的跨源请求(HEAD、GET 和只带有满足 CORS 请求头部的 POST)。响应类型是 opaque,意思是不能读取响应内容
    • same-origin 任何跨源请求都不允许发送

      在通过构造函数手动创建 Request 实例时,默认为 cors;否则,默认为 no-cors

  • redirect 如何处理重定向

    • follow(默认值)跟踪重定向请求,以最终非重定向 URL 的响应作为最终响应
    • error 重定向请求会抛出错误
    • manual 不跟踪重定向请求,而是返回 opaqueredirect 类型的响应,同时仍然暴露期望的重 定向 URL。允许以手动方式跟踪重定向
  • referrer 指定 HTTP 的 Referer 头部内容
    • no-referrer
    • client/about:client 默认值
  • referrerPolicy 指定 HTTP 的 Referer 头部
    • no-referrer 请求中不包含 Referer 头部
    • no-referrer-when-downgrade(默认值)
      • 对于从安全 HTTPS 上下文发送到 HTTP URL 的请求,不包含 Referer 头部
      • 对于从安全 HTTPS 上下文发送到 HTTP URL 的请求,不包含 Referer 头部
    • origin 对于所有请求,将 Referer 设置为只包含源
    • same-origin
      • 对于跨源请求,不包含 Referer 头部
      • 对于同源请求,将 Referer 设置为完整 URL
    • strict-origin
      • 对于从安全 HTTPS 上下文发送到 HTTP URL 的请求,不包含 Referer 头部
      • 对于所有其他请求,将 Referer 设置为只包含源
    • origin-when-cross-origin
      • 对于跨源请求,将 Referer 设置为只包含源
      • 对于同源请求,将 Referer 设置为完整 URL
    • strict-origin-when-cross-origin
      • 对于从安全 HTTPS 上下文发送到 HTTP URL 的请求,不包含 Referer 头部
      • 对于所有其他跨源请求,将 Referer 设置为只包含源
      • 对于同源请求,将 Referer 设置为完整 URL
    • unsafe-url 对于所有请求,将 Referer 设置为完整 URL
  • signal
    • 用于支持通过 AbortController 中断进行中的 fetch()请求 必须是 AbortSignal 的实例
      默认为未关联控制器的 AbortSignal 实例

      常见 Fetch 请求模式

  1. 发送 JSON 数据

    1. let payload = JSON.stringify({
    2. foo: 'bar'
    3. });
    4. let jsonHeaders = new Headers({
    5. 'Content-Type': 'application/json'
    6. });
    7. fetch('/send-me-json', {
    8. method: 'POST', // 发送请求体时必须使用一种 HTTP 方法
    9. body: payload,
    10. headers: jsonHeaders
    11. });
  2. 在请求体中发送参数

    1. let payload = 'foo=bar&baz=qux';
    2. let paramHeaders = new Headers({
    3. 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    4. });
    5. fetch('/send-me-params', {
    6. method: 'POST', // 发送请求体时必须使用一种 HTTP 方法
    7. body: payload,
    8. headers: paramHeaders
    9. });
  3. 发送文件

    1. 请求体支持 FormData,fetch()也可以序列化并发送文件字段中的文件

      1. let imageFormData = new FormData();
      2. let imageInput = document.querySelector("input[type='file']");
      3. imageFormData.append('image', imageInput.files[0]);
      4. fetch('/img-upload', {
      5. method: 'POST',
      6. body: imageFormData
      7. });
    2. 多个文件

      1. let imageFormData = new FormData();
      2. let imageInput = document.querySelector("input[type='file'][multiple]");
      3. for (let i = 0; i < imageInput.files.length; ++i) {
      4. imageFormData.append('image', imageInput.files[i]);
      5. }
      6. fetch('/img-upload', {
      7. method: 'POST',
      8. body: imageFormData
      9. });
  4. 加载 Blob 文件

Fetch API也能提供 Blob 类型的响应,而 Blob 又可以兼容多种浏览器 API。
一种常见的做法是明确将 图片文件加载到内存,然后将其添加到 HTML图片元素。为此,可以使用响应对象上暴露的 blob()方法。这个方法返回一个期约,解决为一个 Blob 的实例。然后,可以将这个实例传给 URL.createObjectUrl() 以生成可以添加给图片元素 src 属性的值

  1. const imageElement = document.querySelector('img');
  2. fetch('my-image.png')
  3. .then((response) => response.blob())
  4. .then((blob) => {
  5. imageElement.src = URL.createObjectURL(blob);
  6. });
  1. 发送跨源请求
    1. 从不同的源请求资源,响应要包含 CORS 头部才能保证浏览器收到响应。没有这些头部,跨源请求 会失败并抛出错误。
    2. 如果代码不需要访问响应,也可以发送 no-cors 请求。此时响应的 type 属性值为 opaque。这种方式适合发送探测请求或者将响应缓存起来供以后使用 ```javascript fetch(‘//cross-origin.com’); // TypeError: Failed to fetch // No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

fetch(‘//cross-origin.com’, { method: ‘no-cors’ }) .then((response) => console.log(response.type)); // opaque

  1. 6. 中断请求
  2. 1. 通过 AbortController/AbortSignal 对中断请求
  3. ```javascript
  4. let abortController = new AbortController();
  5. fetch('wikipedia.zip', { signal: abortController.signal })
  6. .catch(() => console.log('aborted!');
  7. // 10 毫秒后中断请求
  8. setTimeout(() => abortController.abort(), 10);
  9. // 已经中断