添加Workbox离线支持和HTML缓存

huangapple go评论75阅读模式
英文:

Add Workbox offline support and html caching

问题

我正在尝试使用Workbox开始工作。我想将我的网站编写成渐进式Web应用(PWA)。它应该可以离线工作。为此,我想使用CacheFirst策略。我的问题是,Workbox在离线时不起作用。而且我甚至无法在缓存中找到我的主HTML文件。

这是我在主HTML文件中初始化ServiceWorker的部分:

<script>
    if ('serviceWorker' in navigator) {
      window.addEventListener('load', () => {
        navigator.serviceWorker.register('./service-worker.js');
      });
    }
</script>

这是我的service-worker.js文件:

importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js');

workbox.routing.registerRoute(
  /\.html/,
  new workbox.strategies.CacheFirst({
    cacheName: 'html-cache',
  })
);

workbox.routing.registerRoute(
  /\.css$/,
  new workbox.strategies.CacheFirst({
    cacheName: 'css-cache',
  })
);

workbox.routing.registerRoute(
  /\.js/,
  new workbox.strategies.CacheFirst({
    cacheName: 'js-cache',
  })
);

workbox.routing.registerRoute(
  /\.(?:png|jpg|jpeg|svg|gif)$/,
  new workbox.strategies.CacheFirst({
    cacheName: 'image-cache',
    plugins: [
      new workbox.expiration.Plugin({
        maxEntries: 20,
        maxAgeSeconds: 7 * 24 * 60 * 60,
      })
    ],
  })
);

你可以看到我已经进行了初始化并按需设置。在开发控制台中可以看到缓存,但正如你所看到的,没有html-cache。为什么呢?而且再次强调它无法在离线时工作。附加信息:我正在通过HTTPS运行网站,因为这对于服务工作者是必需的。希望有人能帮助我。

~Marcus

英文:

I am trying to start with workbox. I want to code my website as PWA. It should work offline. And for this, I want to use the CacheFirst Strategy. My Problem is, that the workbox doesnt work offline. And I even can not find my main html file in the cache.
Here is my initialization of my ServiceWorker in the main html file:

&lt;script&gt;
    if (&#39;serviceWorker&#39; in navigator) {
      window.addEventListener(&#39;load&#39;, () =&gt; {
        navigator.serviceWorker.register(&#39;./service-worker.js&#39;);
      });
    }
  &lt;/script&gt;  

And here is my service-worker.js file:

importScripts(&#39;https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js&#39;);

workbox.routing.registerRoute(
  /\.html/,
  new workbox.strategies.CacheFirst({
    cacheName: &#39;html-cache&#39;,
  })
);

workbox.routing.registerRoute(
  /\.css$/,
  new workbox.strategies.CacheFirst({
    cacheName: &#39;css-cache&#39;,
  })
);

workbox.routing.registerRoute(
  /\.js/,
  new workbox.strategies.CacheFirst({
    cacheName: &#39;js-cache&#39;,
  })
);

workbox.routing.registerRoute(
  /\.(?:png|jpg|jpeg|svg|gif)$/,
  new workbox.strategies.CacheFirst({
    cacheName: &#39;image-cache&#39;,
    plugins: [
      new workbox.expiration.Plugin({
        maxEntries: 20,
        maxAgeSeconds: 7 * 24 * 60 * 60,
      })
    ],
  })
);

You see I initialize it and set it up as need. Here you can see the caches in the dev console. But as you can see there is no html-cache. Why? And again it doesn't work offline. Additional info: I am running the website over HTTPS as it is needed for the service worker. Hope somebody can help me.
~Marcus

答案1

得分: 1

HTML不会被缓存,因为它们很可能在没有.html扩展名的情况下加载或链接,就像这样:

https://example.com/

&lt;a href=&quot;/about&quot;&gt;About&lt;/a&gt;

然而,用于匹配HTML页面请求的正则表达式检查了.html扩展名:

workbox.routing.registerRoute(
  /\.html/,
  ...
);

CSS、JS和图像资源可以正确缓存,因为它们很可能使用其文件扩展名加载,这与传递给Workbox的RegExp模式匹配。

要修复这个问题,请确保用于请求HTML页面的URL与模式匹配。一种方法是访问它们或链接到它们时使用.html扩展名:

https://example.com/index.html
https://example.com/about.html

&lt;a href=&quot;/about.html&quot;&gt;About&lt;/a&gt;

大多数情况下,希望使用没有.html扩展名的URL。为了在这种情况下仍然缓存HTML页面,可以使用其他方式来匹配URL。Workbox支持许多路由请求的方式:使用字符串、正则表达式或回调函数。文档提供了何时使用每种方式的良好解释。一个可能的方法如下(这可以简单或复杂,根据需要进行调整):

function matchFunction({ url }) {
  const pages = [&#39;/&#39;, &#39;/about&#39;];
  return pages.includes(url.pathname);
}

workbox.routing.registerRoute(
  matchFunction,
  new workbox.strategies.CacheFirst({
    cacheName: &#39;html-cache&#39;
  })
);
英文:

The HTML are not getting cached because most likely they are being loaded or linked to without the .html extension, like so:

https://example.com/

&lt;a href=&quot;/about&quot;&gt;About&lt;/a&gt;

However, the RegExp used to match requests to HTML pages checks for the .html extension:

workbox.routing.registerRoute(
  /\.html/,
  ...
);

The CSS, JS, and image resources are being cached properly because they are most likely being loaded with their file extensions, which matches the RegExp patterns passed to Workbox.

To fix this, make sure that the URLs used to request the HTML pages match the pattern. One way to achieve this is to visit them or link to them them with the .html extension:

https://example.com/index.html
https://example.com/about.html

&lt;a href=&quot;/about.html&quot;&gt;About&lt;/a&gt;

Most of the time, it's desirable to use URLs without the .html extension. To still cache the HTML pages in this case, other ways of matching the URLs can be used. Workbox supports many ways to route requests: using a string, RegExp, or a callback function. The documentation provides a good explanation of when it's appropriate to use each one. One way this could look like would be (this can be as simple or complex as necessary):

function matchFunction({ url }) {
  const pages = [&#39;/&#39;, &#39;/about&#39;];
  return pages.includes(url.pathname);
}

workbox.routing.registerRoute(
  matchFunction,
  new workbox.strategies.CacheFirst({
    cacheName: &#39;html-cache&#39;
  })
);

huangapple
  • 本文由 发表于 2020年1月6日 19:22:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/59611238.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定