首页 > 解决方案 > 使用 networkFirst 策略的 Workbox 回退响应

问题描述

我在我的服务工作人员中使用 Workbox,我使用此策略来提供对在脱机和页面不在缓存中时应该显示的路由的回退响应:

const FALLBACK_URL = '/offline/';

const urlHandler = workbox.strategies.staleWhileRevalidate({
    cacheName: 'page-cache'
});

workbox.routing.registerRoute(
    /\/.+\//,
    ({event}) => {
        return urlHandler.handle({event})
            .catch(() => caches.match(FALLBACK_URL));
    });

当我使用 staleWhileRevalidate 策略和使用 networkOnly 策略时,这很好用(我已经缓存了 FALLBACK_URL)。但是,我真的很想使用 networkFirst 策略,但是当我尝试访问不在缓存中的页面时出现以下错误:

在此处输入图像描述

控制台说

““ https://staging.bassbuddha.com/pedals/ ”的 FetchEvent导致网络错误响应:一个不是响应的对象被传递给了 respondWith()。

在此处输入图像描述

我究竟做错了什么?

我正在使用版本 3.4.1 https://storage.googleapis.com/workbox-cdn/releases/3.4.1/workbox-sw.js

标签: service-workerworkbox

解决方案


事实证明,根据 Workbox GitHub repo 上的这个问题,这是故意的。这是 jeffposnick 在 networkFirst 上的引用(相对于其他策略):

networkFirst 在这种情况下最终不会抛出,因为底层网络异常会触发 cache.match() 查找,并且 cache.match() 在缓存未命中时不会抛出/拒绝。相反,它以 undefined 解析。

因此,在 Workbook 中使用 networkFirst 回退的解决方案是在响应中捕获undefined并将其与回退 url 匹配,如下所示:

const FALLBACK_URL = '/offline/';

const urlHandler = workbox.strategies.networkFirst({
    cacheName: 'page-cache'
});

workbox.routing.registerRoute(
    /\/.+\//,
    ({event}) => {
        return urlHandler.handle({event})
            .then((response) => {
                return response || caches.match(FALLBACK_URL);
            })
            .catch(() => caches.match(FALLBACK_URL));
    });

推荐阅读