首页 > 解决方案 > 为什么 workbox 和 vue 不提供缓存中的文件?

问题描述

我的情况很简单。我想在刷新页面并且没有网络连接时显示自定义离线页面。

所以我使用带有 workbox pwa 的 cli 创建了一个 vue 应用程序。

这就是 vue.config.js 的样子:

module.exports = {
  pwa: {
    workboxPluginMode: 'InjectManifest',
    workboxOptions: {
      swSrc: 'public/service-worker.js',
      swDest: 'service-worker.js',
    }
  }
};

我将此内容添加到public/offline.html

<html>I'm the offline page</html>

public/service-worker.js我确实有这个代码:

// public/service-worker.js

const offlinePage = '/offline.html';
workbox.setConfig({
  debug: true
});

workbox.core.setCacheNameDetails({ prefix: 'my-app' });

self.addEventListener('message', event => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
});

const customHandler = async args => {
  console.log('in customHandler!!1 route');
  return (await caches.match(offlinePage));
};

workbox.routing.registerRoute('/', customHandler);

self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});

并运行以下命令:

npm run build &&  http-server -p 3001 dist

现在,我使用浏览器访问 localhost:3001 并且应用程序已启动:Service worker has been registered.

我还看到/offline页面被缓存。

在此处输入图像描述

问题是当我打开“离线”复选框并刷新时。

我得到了 404。而不是离线页面。

在此处输入图像描述

最奇怪的是我在缓存中什么都没有

在此处输入图像描述

不知道为什么会这样。如何在失去网络连接时提供离线页面?

标签: vue.jsservice-workerprogressive-web-appsworkbox

解决方案


尝试重现后,我从您的代码中发现了一些错误。

http://localhost:3001/ ”的 FetchEvent 导致网络错误响应:一个不是响应的对象被传递给了 respondWith()。

这一定意味着您的退货声明有问题:

return (await caches.match(offlinePage))

我发现了更多奇怪的行为。当我尝试重新加载时,页面会像离线一样崩溃。这意味着您的处理程序代码也是错误的。

const customHandler = async args => {
  console.log('in customHandler!!1 route');
  return (await caches.match(offlinePage));
};

workbox.routing.registerRoute('/', customHandler);

从您的代码中,这意味着:我不在乎我是在线还是离线,我将返回缓存。

我对工作箱不太熟悉,但我尝试根据这个Cache.match修复该错误:

const customHandler = async args => {
  try {
    // try to load the index.html first
    return await fetch(args.event.request)
  } catch {
    // get cache name since it auto-generated from workbox
    let cache = await caches.open(workbox.core.cacheNames.precache)

    // get url name this can't just be '/offline' since workbox add some auto-generated name
    let url = workbox.precaching.getCacheKeyForURL(offlinePage)

    return caches.match(url)
  }
};

推荐阅读