25

我正在使用 sw-precache 通过 Polymer CLI 构建过程生成我的服务工作,因此它旨在更新已更新文件的哈希以表示需要更新缓存。但是我更新的内容没有在缓存中被替换,所以如果我用 ctrl+r 刷新它会得到一个旧版本,但如果我用 ctrl+shift+r 刷新它就会得到新版本。一个原因可能是我的服务人员没有更新。

该文档指出

如果 service worker 文件与它当前拥有的文件相比甚至有一个字节的差异,它就会认为它是新的。

,但是如果我的新服务人员没有更改一个字节怎么办?(如果只有一个哈希发生了变化,就会发生这种情况)。如何配置 sw-precache 以在每次新请求时更新服务工作?

4

6 回答 6

15

'sw-precache' 已被Workbox取代,它为您要预缓存的文件生成哈希并将其添加到服务工作者的源代码中(我不知道是否sw-precache以相同的方式工作,杰夫的回答表明确实如此)。如果您要预缓存的任何文件发生变化——并且你重新运行构建——更新后的服务工作者中的哈希值也会更新,这几乎可以保证服务工作者将“至少有一个字节不同”。

当您重新加载(ctrl-r)或重新访问您的应用程序时,浏览器将再次获取为其注册的服务工作者。而且,如果那个 service worker 发生了变化,它将被“排队”来管理应用程序。但它不会开始管理应用程序,直到您在应用程序打开的情况下关闭所有选项卡,然后打开一个新选项卡。

当您硬刷新 ( shift-ctrl-r)时,它总是会在没有控制器的情况下加载,这与使用新的服务工作者不同。

为了在开发过程中进行测试,我在 devtools 中使用skip waiting来让新的 service worker 替换旧的,而无需等待我关闭所有选项卡。

于 2017-10-19T10:24:35.993 回答
14

正如前面的答案所述,浏览器有 1 天(24 小时)的内置限制来查找服务工作者的更新,但您需要注意的是您仍然需要调用.update()您的ServiceWorkerRegistration对象,否则原始将使用文件的版本。

在 Chrome 中测试更改时,我总是右键单击刷新按钮并在处理我的服务工作者脚本时选择“空缓存和硬重置”(当开发人员工具打开时选项可用)。

于 2017-08-29T19:35:06.187 回答
11

如果一个文件的 hash 发生变化,那足以确保 service worker 生成的 JavaScript 文件发生sw-precache变化。反过来,这足以触发 service worker 更新流程。

如果您在测试时没有看到触发更新流,则可能是由于服务工作者 JavaScript 文件使用 HTTP 缓存标头提供,导致它从浏览器的缓存中获取,而不是从网络中获取。

请参阅https://stackoverflow.com/a/38854905/385997,了解有关 HTTP 缓存标头如何发挥作用以及与此相关的最佳实践的讨论。

于 2017-01-31T16:40:55.797 回答
1

从 UX 的角度来看,我实现的一个选项是在你的 service worker 上调用 unregister 方法。( https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/unregister )

注销过程完成后,您可以:

  1. 强制窗口刷新(window.location.reload)
  2. 根据您的加载过程,您可以获取新的服务工作者,它有望缓存您的所有新内容。

我之前遇到过 Service Worker 的奇怪问题,因此这种类型的解决方案允许您在一定程度上清除旧缓存并刷新应用程序的状态,而无需强制用户清除其实际浏览器缓存,同时重新加载您的应用程序.

EX(如何注销):

serviceworker.unregister()
    .then( unregResult => { 
       //You can check if successful with Promise result 'unregResult'
       window.location.reload();
    })
于 2020-09-08T15:16:01.127 回答
1

将版本号存储在service‑worker.js

控制中的一个字符更改service-worker.js将自动触发 PWA 更新。因此,如果您将版本号存储const在此文件中并更改它,则会触发 PWA 的更新。

最终如何处理更新由service-worker.js. 可以根据 PWA 资产的规模和波动性来定义不同的更新策略。

但是,有一个重要的警告。确保资产服务器上文件设置的浏览器缓存到期指令设置.htaccess为非常短的持续时间(例如hours),甚至设置为。如果不这样做,将导致浏览器在未来几天内看不到.manifest.jsonservice-worker.js.

有关服务工作者行为的更多详细信息,请参阅Google Web Fundamentals

于 2021-03-24T14:43:25.303 回答
-2
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {

    //Force the Service Worker to Upddate
    self.registration.update();

    const notification = JSON.parse(payload.data.notification);
    return self.registration.showNotification(notification.title, notification);

});
于 2019-11-12T10:29:08.623 回答