如何在PWA中更新service worker缓存?

14

我使用 sw-toolbox 库来编写 service worker。我的 PWA 缓存除 API 查询以外的所有内容(图片、CSS、JS、HTML)。但如果某些文件有一天被更改了怎么办?或者如果 service-worker.js 被更改了怎么办?应用程序应该如何检测文件的更改?

我的 service-worker.js:

'use strict';
importScripts('./build/sw-toolbox.js');

self.toolbox.options.cache = {
  name: 'ionic-cache'
};

// pre-cache our key assets
self.toolbox.precache(
  [
    './build/main.js',
    './build/main.css',
    './build/polyfills.js',
    'index.html',
    'manifest.json'
  ]
);

// dynamically cache any other local assets
self.toolbox.router.any('/*', self.toolbox.cacheFirst);

// for any other requests go to the network, cache,
// and then only use that cached resource if your user goes offline
self.toolbox.router.default = self.toolbox.networkFirst;

我不知道在PWA中更新缓存的常规方法。也许PWA应该在后台发送AJAX请求并检查UI版本?

5个回答

4
据我所知,sw_toolbox没有缓存与网络更新的策略。这真的是你想要的。你想修改缓存-网络竞争策略 - > https://jakearchibald.com/2014/offline-cookbook/#cache-network-race。不仅要让失败者消失,一旦网络响应,你还需要更新客户端。这比我在这里有时间或时间解释的要高级一些。我会向客户端发布一条消息,让它知道有一个更新。你可能想提醒用户更新或强制更新。我认为这不是边缘情况,而是非常普遍但高级的场景。我希望很快能发布更详细的解决方案。

4
我处理了服务工作者,没有使用任何库,最终想出的解决方案涉及一些服务器端代码和一些客户端代码。策略简述如下:
首先,需要哪些变量以及它们在哪里:
1. 在服务器端有一个“服务工作者版本”变量(如果您使用像php这样的东西,它将在服务器端立即更新而不需要重新部署,则将其放入数据库或配置文件中)。我们称之为 serverSWVersion 2. 在您缓存的javascript文件中的一个文件上(我有一个专门用于此目的的javascript文件),有一个全局变量,也将是“服务工作者版本”。我们称之为 clientSWVersion 现在如何使用这两个变量:
  1. 每当一个人登陆页面时,向服务器发起ajax调用,获取 serverSWVersion 值。将其与 clientSWVersion 值进行比较。

  2. 如果这两个值不同,则说明您的Web应用程序版本不是最新的。

  3. 如果是这种情况,则注销服务工作者并刷新页面,以便重新注册服务工作者并缓存新文件。

有新文件可用时该怎么做

  1. 更新 serviceSWVersionclientSWVersion 变量,并在适用的情况下上传到服务器。

  2. 当用户再次访问时,服务工作者应该被重新注册,所有缓存的文件将被检索。

我提供了一个基于php服务器端的代码,这是我在实施此策略时使用的。它应该能向您展示原则。只需将“Exercise”文件夹放入php服务器的htdocs中,它就可以工作,而无需进行其他任何操作。希望您会发现它有用...并记住,如果您使用的是其他服务器而不是php,您可以使用数据库来存储服务器端服务工作者变量,而不是配置文件:
代码压缩包: ServiceWorkerExercise.zip

4

这里有一个不错的解决方案,写在这里。他简要地提到了两种方法:要么不使用缓存优先策略,要么更新用户体验模式,显示“重新加载以获取最新更新”。


1
当服务工作者被修改时,浏览器会安装它,但新版本直到关闭并重新打开浏览器标签或PWA应用程序窗口后才会被激活。因此,如果更改缓存名称,则在浏览器重新打开之前,新缓存将不会提供任何文件,并且旧缓存也不会被删除。您可以使用registration.onupdatefound在页面JavaScript中检测服务工作者的更改,并要求用户关闭并重新打开窗口 - 就像这样:

// register the service worker
 navigator.serviceWorker.register('sw.js').then(function(registration) 
 {
  registration.onupdatefound = function()
  {
   console.log("ServiceWorker update found.");
   alert("A new version is available - please close this browser tab or app window and re-open to update ... ");
  }
 }, function(err)
 {
  console.log('ServiceWorker registration failed: ', err);
 });


0

将 self.toolbox.router.any('/', self.toolbox.cacheFirst); 更改为 self.toolbox.router.any('/', self.toolbox.fastest);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接