Workbox-cacheable-response

在运行时缓存资源时,对于给定响应是否“有效”以及是否符合保存和重复使用条件,并没有放之四海而皆准的规则。

workbox-cacheable-response 模块提供了一种标准方法来根据以下因素确定是否应缓存响应:响应的数字状态代码、是否存在具有特定值的标头,或者两者的组合。

基于状态代码缓存

您可以通过向策略的 plugins 参数添加 CacheableResponsePlugin 实例来配置 Workbox 策略,以将一组状态代码视为符合缓存条件:

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

registerRoute(
  ({url}) =>
    url.origin === 'https://third-party.example.com' &&
    url.pathname.startsWith('/images/'),
  new CacheFirst({
    cacheName: 'image-cache',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200],
      }),
    ],
  })
);

此配置告知 Workbox,在处理针对 https://third-party.example.com/images/ 的请求的响应时,缓存状态代码为 0200 的所有请求。

基于标头的缓存

您可以在构建插件时设置 headers 对象,从而配置 Workbox 策略以检查是否存在特定标头值作为添加到缓存的条件:

import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

registerRoute(
  ({url}) => url.pathname.startsWith('/path/to/api/'),
  new StaleWhileRevalidate({
    cacheName: 'api-cache',
    plugins: [
      new CacheableResponsePlugin({
        headers: {
          'X-Is-Cacheable': 'true',
        },
      }),
    ],
  })
);

处理包含 /path/to/api/ 的请求网址的响应时,请查看名为 X-Is-Cacheable 的标头(该标头将由服务器添加到响应中)。如果该标头存在且设置为“true”,则可缓存响应。

如果指定了多个标头,则只需其中一个标头与关联值匹配。

基于标头和状态代码进行缓存

您可以混用状态和标头配置。必须同时满足这两个条件,响应才会被视为可缓存;换言之,响应必须具有一个配置的状态代码,并且必须至少包含一个所提供的标头。

import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

registerRoute(
  ({url}) => url.pathname.startsWith('/path/to/api/'),
  new StaleWhileRevalidate({
    cacheName: 'api-cache',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [200, 404],
        headers: {
          'X-Is-Cacheable': 'true',
        },
      }),
    ],
  })
);

什么是默认值?

如果您使用 Workbox 的某个内置策略而未明确配置 cacheableResponse.CacheableResponsePlugin,则以下默认条件用于确定是否应缓存从网络收到的响应:

  • stalewhileRevalidate 和 networkFirst:状态为 0(即不透明响应)或 200 的响应被视为可缓存。
  • cacheFirst:状态为 200 的响应被视为可缓存。

默认情况下,响应标头不用于确定可缓存性。

为什么有不同的默认值?

默认值将围绕状态为 0 的响应(即不透明响应)是否最终缓存而有所不同。由于不透明响应具有“黑盒”特性,因此 Service Worker 无法知道响应是否有效,或者它是否反映了从跨源服务器返回的错误响应。

如果策略包含某些更新缓存响应的方法(例如 stalewhileRevalidate 和 networkFirst),由于下次更新缓存时,将会使用正确、成功的响应,从而降低缓存暂时错误响应的风险。

如果策略涉及缓存接收的第一个响应并无限期地重复使用已缓存的响应,缓存并重复使用瞬时错误的影响会更加严重。为了安全起见,默认情况下,cacheFirst 将拒绝保存响应,除非其状态代码为 200

高级用法

如果要在 Workbox 策略之外使用相同的缓存逻辑,可以直接使用 CacheableResponse 类。

import {CacheableResponse} from 'workbox-cacheable-response';

const cacheable = new CacheableResponse({
  statuses: [0, 200],
  headers: {
    'X-Is-Cacheable': 'true',
  },
});

const response = await fetch('/path/to/api');

if (cacheable.isResponseCacheable(response)) {
  const cache = await caches.open('api-cache');
  cache.put(response.url, response);
} else {
  // Do something when the response can't be cached.
}

类型

CacheableResponse

您可以使用此类设置规则,以确定需要存在哪些状态代码和/或标头才能使 Response 被视为可缓存。

属性

  • 构造函数

    void

    如需构造新的 CacheableResponse 实例,您必须至少提供一个 config 属性。

    如果同时指定了 statusesheaders,必须同时满足这两个条件,Response 才会被视为可缓存。

    constructor 函数如下所示:

    (config?: CacheableResponseOptions) => {...}

  • isResponseCacheable

    void

    根据此对象的配置检查响应以查看其是否可缓存。

    isResponseCacheable 函数如下所示:

    (response: Response) => {...}

    • 条回复

      响应

      要检查其可缓存性的响应。

    • 返回

      boolean

      如果 Response 可缓存,则为 true;否则,为 false

CacheableResponseOptions

属性

  • headers

    对象(可选)

  • statuses

    number[] 选填

CacheableResponsePlugin

实现 cacheWillUpdate 生命周期回调的类。这样可以更轻松地向通过 Workbox 的内置策略发出的请求添加可缓存性检查。

属性

  • 构造函数

    void

    如需构造新的 CacheableResponsePlugin 实例,您必须至少提供一个 config 属性。

    如果同时指定了 statusesheaders,必须同时满足这两个条件,Response 才会被视为可缓存。

    constructor 函数如下所示:

    (config: CacheableResponseOptions) => {...}