如何使用 Workbox setDefaultHandler

How to use Workbox setDefaultHandler

我正在从 sw-toolbox 切换到 Workbox,但我不知道如何使用 setDefaultHandler()

如果我尝试(如上面链接的文档中所述):

workboxSW.router.setDefaultHandler({
    handler: new workbox.runtimeCaching.CacheFirst()
});

我收到一个错误,指出 runtimeCaching 未定义:

Uncaught ReferenceError: router is not defined

所以..我该如何使用它并以类似于我配置 sw-toolbox 的方式配置它:

toolbox.options.cache = {
    name: "default",
    maxEntries: 128,
    maxAgeSeconds: (60*60*24), // 24hrs
};
toolbox.router.default = toolbox.cacheFirst;

我希望能够做这样的事情:

workboxSW.router.setDefaultHandler({
    handler: workboxSW.strategies.cacheFirst({
        cacheName: 'default',
        cacheExpiration: {
            maxEntries: 128,
        },
        cacheableResponse: {statuses: [0, 200]},
    })
});

..它不会抛出编译错误但是当我使用它时我得到这个:

Uncaught (in promise) TypeError: Request method 'POST' is unsupported

..我的 'default' 的缓存存储仍然是空的..?

workboxSW.router.setDefaultHandler({
  handler: workboxSW.strategies.cacheFirst({...})
});

大体上是正确的语法。

我相信你看到了

Uncaught (in promise) TypeError: Request method 'POST' is unsupported

因为所有不匹配任何显式路由的 HTTP 请求都会触发默认处理程序,包括 HTTP POST 请求。但是 HTTP POST 请求不能与缓存存储 API 一起使用,当缓存优先策略尝试存储 [=30] 时,将抛出类似于您所看到的异常=] 对在缓存中。

在这种特殊情况下,当您知道您的 Web 应用程序将发出 HTTP POST 请求时,您可以采用以下两种方法之一。

您可以在默认处理程序中检查请求类型,并且仅将缓存优先策略应用于 GET 个请求:

workboxSW.router.setDefaultHandler({
  handler: (args) => {
    if (args.event.request.method === 'GET') {
      return workboxSW.strategies.cacheFirst(args);
    }
    return fetch(args.event.request);
  },
});

或者,您可以创建匹配所有请求的通配符路由,并利用默认情况下路由仅匹配 HTTP GET:

的事实
workboxSW.router.registerRoute(
  /./, // This should match all requests.
  workboxSW.strategies.cacheFirst({...}),
  'GET' // This is the default, and can be left out.
);

由于我对 Jeff 的第一个解决方案的编辑被拒绝,我将继续自己提交答案。

Jeff 的样本很接近。他建议:

You could check for the request type in the default handler, and only apply the cache-first strategy to GET requests:

workboxSW.router.setDefaultHandler({
  handler: (args) => {
    if (args.event.request.method === 'GET') {
      return workboxSW.strategies.cacheFirst(args);
    }
    return fetch(args.event.request);
  },
});

这是正确的方法,但他提供的示例代码不起作用。处理程序参数需要一个处理程序,而不是一个策略。幸运的是,策略只有一个 (public) 方法,称为 "handle".

所以我稍微修改了他的代码;首先,我创建了一个名为 defaultStrategy 的策略,其中包含我需要的所有选项。然后,在 setDefaultHandler 调用中,我 return defaultStrategy.handle(args) 而不是 CacheFirst 构造函数。而已!

// Register 'default'
var defaultStrategy = workboxSW.strategies.cacheFirst({
    cacheName: "default",
    cacheExpiration: {
        maxEntries: 128,
        // more options..
    },
    cacheableResponse: {statuses: [0, 200]},
});
workboxSW.router.setDefaultHandler({
    handler: (args) => {
        if (args.event.request.method === 'GET') {
            return defaultStrategy.handle(args);
        }
        return fetch(args.event.request);
    },
});

更新:Workbox v3

正如我在下面的评论中指出的那样,上面的代码不适用于 Workbox v3。改用这个:

// Register 'default'
var defaultStrategy = workbox.strategies.cacheFirst ({
    cacheName: "your.cache.name",
    plugins: [
        new workbox.expiration.Plugin({
            maxEntries: 128,
            maxAgeSeconds: 7 * 24 * 60 * 60, // 1 week
            purgeOnQuotaError: true, // Opt-in to automatic cleanup
        }),
        new workbox.cacheableResponse.Plugin({
            statuses: [0, 200] // for opague requests
        }),
    ],
});
workbox.routing.setDefaultHandler(
    (args) => {
        if (args.event.request.method === 'GET') {
            return defaultStrategy.handle(args); // use default strategy
        }
        return fetch(args.event.request);
    }
);