PWA系列——Fetch API

Posted JS菌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PWA系列——Fetch API相关的知识,希望对你有一定的参考价值。

PWA系列——Fetch API

今天聊聊 xhr 的替代品 Fetch,在全局作用域中有个 fetch 方法方便使用。虽然同样也是处理 HTTP 请求和响应的,但 fetch 有两个不同之处,一个是收到错误的 HTTP 状态码时,fetch 方法返回的 Promise 不会被 reject,而是将 resolve 的对象中名为 ok 属性设置为 false,只有在网络出现故障的情况下才会被 reject。另外一个不同之处就是默认不会发送和接收 cookies,如果需要那么必须手动设置 credentials

使用 Fetch 我们需要了解 fetch、Request、Response、Headers 以及 Body,这几个都是使用 Fetch API 所需要了解的。

fetch

作为全局作用域中的 fetch,首先我们需要快速了解一下 fetch 方法如何调用(参考 MDN):

  • 他可以接收一个 USVString 字符串或者一个 Request 对象(下文会讲到 Request 对象)

  • 以及一个可选的配置参数(配置参数包括一系列对请求的设置可选的参数有):

  • method: 请求使用的方法

  • headers: 请求的头信息,形式为 Headers 的对象 或包含 ByteString 值的对象字面量

  • body: 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象 。注意 GET 或 HEAD 方法的请求不能包含 body 信息。

  • mode: 请求的模式,如 cors、 no-cors 或者 same-origin。

  • credentials: 请求的 credentials,如 omit、same-origin 或者 include。为了在当前域名内自动发送 cookie ,必须提供这个选项,从 Chrome 50 开始, 这个属性也可以接受 FederatedCredential 实例或是一个 PasswordCredential 实例。

  • cache: 请求的 cache 模式: default 、 no-store 、 reload 、 no-cache 、 force-cache 或者 only-if-cached 。

  • redirect: 可用的 redirect 模式: follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误), 或者 manual (手动处理重定向). 在Chrome中,Chrome 47之前的默认值是 follow,从 Chrome 47开始是 manual。

  • referrer: 一个 USVString 可以是 no-referrer、client或一个 URL。默认是 client。

  • referrerPolicy: Specifies the value of the referer HTTP header. May be one of no-referrer、 no-referrer-when-downgrade、 origin、 origin-when-cross-origin、 unsafe-url 。

  • integrity: 包括请求的  subresource integrity 值 ( 例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=)。

看个例子:

通过 fetch 发送 png 图片请求,并使用 blob 方法和 createObjectUrl 方法将数据转为 Object URL,并通过 img 元素显示出来:

+(async function () {
+    // 创建 url
+    let url = new URL('https://httpbin.org/image/png')
+})()

首先创建一个 url 实例

; (async function () {
    // 创建 url
    let url = new URL('https://httpbin.org/image/png')
    // 创建 header 头
+   let header = new Headers({
+       'X-Custom-Header': 'custom header value'
+   })
})()

创建实例 header 头,接收自定义请求头信息

(async function () {
    // 创建 url
    let url = new URL('https://httpbin.org/image/png')
    // 创建 header 头
    let header = new Headers({
        'X-Custom-Header': 'custom header value'
    })
+   // 创建 request 请求
+   let request = new Request(url, {
+       method: 'GET',
+       headers: header
+   })
})()

创建 request 请求,将 url header 等必要信息传入到 Request 构造函数

(async function () {
    // 创建 url
    let url = new URL('https://httpbin.org/image/png')
    // 创建 header 头
    let header = new Headers({
        'X-Custom-Header': 'custom header value'
    })
    // 创建 request 请求
    let request = new Request(url, {
        method: 'GET',
        headers: header
    })
+   // 接收 resposne 响应
+   let response = await fetch(request)
+   let blobData = await response.blob() // 接收 blob 对象
})()

最后通过 fetch 并将 request 作为参数传入发起请求,并通过 response 响应对象的 blob 方法接收到图片数据

(async function () {
    // 创建 url
    let url = new URL('https://httpbin.org/image/png')
    // 创建 header 头
    let header = new Headers({
        'X-Custom-Header': 'custom header value'
    })
    // 创建 request 请求
    let request = new Request(url, {
        method: 'GET',
        headers: header
    })
    // 接收 resposne 响应
    let response = await fetch(request)
    let blobData = await response.blob() // 接收 blob 对象

+   let objUrl = URL.createObjectURL(blobData) // 转为 Object URL

+   let img = new Image()
+   img.src = objUrl
+   document.body.appendChild(img)
})()

最后调用 URL 静态方法 createObjectURL 将 blob 对象转为 ObjectURL 创建 img 并追加到 body 中

上述涉及到了 Request、Response、Headers 构造函数,我们再来看看这三个构造函数分别接收什么参数以及包括什么属性和方法吧

Request 请求

Request 构造函数接收的参数跟 fetch 方法一样,URL 链接、Request 对象、以及一系列可选参数如:

(async function () {
    let myRequest = new Request('./demo.jpeg', {
        method'GET',
        headers: {
            'Content-Type''image/jpeg'
        },
        mode'cors',
        cache'default'
    })
})()

Request 实例

同时他也支持传入另一个 Request 实例,通过构造器可创建一个请求的副本。

(async function () {
    let myRequest = new Request('./demo.jpeg', {
        method: 'GET',
        headers: {
            'Content-Type': 'image/jpeg'
        },
        mode: 'cors',
        cache: 'default'
    })
+   let myRequest1 = new Request(myRequest)
})()

另外,Request 实现了 Body 的一系列方法,如 blob 获取请求实体的 blob,json 方法返回 body 的 json 数据

  • Body.arrayBuffer() 返回解决一个ArrayBuffer表示的请求主体的promise.

  • Body.blob() 返回解决一个Blob表示的请求主体的promise.

  • Body.formData() 返回解决一个FormData表示的请求主体的promise.

  • Body.json() 返回解决一个JSON表示的请求主体的promise.

  • Body.text() 返回解决一个USVString(文本)表示的请求主体的promise.

比如:

(async function () {
    let myRequest = new Request('./demo', {
        method'POST',
        mode'cors',
        cache'default',
        bodyJSON.stringify({ name'oli' })
    })

    let data = await myRequest.json() // 获取到的 data 为 parsed json 数据
})()

同样的上述 Body 在 Response 示例中也有实现。

Response 响应

通过 new 操作符创建 Reponse 的实例,Response 实例并非一定需要发送真正的请求才可获得。通过构造函数我们可以自己去构造一个 Response 实例

以上是关于PWA系列——Fetch API的主要内容,如果未能解决你的问题,请参考以下文章

为啥浏览器不在通过 fetch API 检索的 HTML 片段中运行 <script>? [复制]

如何使用 fetch 从一个模块导出从 GET API 获得的响应数据到另一个模块

iis不支持pwa

PWA(Progressive Web App)入门系列:PWA简介

PWA(Progressive Web App)入门系列:PWA简单介绍

Angular 学习笔记 ( PWA + App Shell )