14

我使用带有sw-toolbox库的服务人员。我的 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 版本?

4

5 回答 5

4

AFAIK sw_toolbox 没有网络更新缓存策略。我想这真的是你想要的。您想修改缓存网络竞赛策略 - > https://jakearchibald.com/2014/offline-cookbook/#cache-network-race 而不是让失败者消失,一旦网络响应,您将想要更新客户端。这有点高级,我有时间或时间在这里解释一下。我会向客户发布一条消息,让它知道有更新。您可能希望提醒用户注意更新或只是强制更新。我不认为这是一个边缘案例,而是一个非常常见但高级的场景。我希望尽快发布更详细的解决方案。

于 2017-06-19T20:28:02.640 回答
4

这里写了一个很好的解决方案,他声明(简而言之)要么不使用缓存优先策略,要么更新显示“重新加载以获取最新更新”的 UX 模式。

于 2017-06-21T00:49:53.343 回答
4

我在不使用任何库的情况下与服务人员打交道,我最终提出的解决方案涉及一些服务器端代码和一些客户端。简而言之策略

首先是您需要的变量和位置:

  1. 在服务器端有一个“服务工作者版本”变量(如果您使用的是 php 之类的东西,则将其放入数据库或配置文件中,它将立即在服务器端更新而无需重新部署。我们称之为serverSWVersion
  2. 在您缓存的其中一个 javascript 文件上(我有一个专用于此的 javascript 文件)有一个全局变量,它也将是“服务工作者版本”。我们称之为clientSWVersion

现在如何使用这两个:

  1. 每当有人登陆页面时,对您的服务器进行 ajax 调用以获取serverSWVersion值。将此值与clientSWVersion值进行比较。

  2. 如果值不同,则意味着您的 Web 应用程序版本不是最新的。

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

新文件可用时实际执行的操作

  1. 更新serviceSWVersionclientSWVersion变量并上传到适用的服务器。

  2. 当一个人再次访问时,应该重新注册 service worker,并检索所有缓存的文件。

我提供了一个基于 php 服务器端的代码,我在实施此策略时使用了该代码。它应该向您展示这些原则。只需将“Exercise”文件夹放在 php 服务器的 htdocs 中,它就可以工作,而无需您做任何其他事情。我希望你觉得它很有用......请记住,如果你使用的是其他服务器而不是 php,你可以只使用数据库而不是配置文件来存储服务器端服务工作者变量:

带有代码的 Zip 文件: ServiceWorkerExercise.zip

于 2017-07-05T06:02:57.757 回答
1

当 Service Worker 发生更改时,浏览器将安装它,但新版本将在浏览器选项卡或 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);
	});

于 2020-03-20T11:50:05.223 回答
0

改变 self.toolbox.router.any('/ ', self.toolbox.cacheFirst); to self.toolbox.router.any('/ ', self.toolbox.fastest);

于 2018-01-05T01:54:35.430 回答