Html 如何强制 Service Worker 更新?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41903097/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 14:18:58  来源:igfitidea点击:

How to force service worker to update?

htmlservice-workeroffline-cachingprogressive-web-appssw-precache

提问by Jp_

I'm using sw-precache to generate my service work with Polymer CLI build process, so it's intended to update the hash of updated files to signal a need to update the cache. But my updated content is not being replaced in cache, so it's getting an old version if I refresh with ctrl+r but the new version if I refresh with ctrl+shift+r. A reason for that can be that my service worker is not being updated.

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

This docstates that

该文档指出

If there is even a byte's difference in the service worker file compared to what it currently has, it considers it new.

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

, but what if my new service worker didn't change a byte? (as it happens if just one hash has changed). How to configure the sw-precache to update the service work at every new request?

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

回答by Jeff Posnick

If one file's hash changes, that's enough to ensure that the service worker JavaScript file generated by sw-precachechanges. That, in turn, is enough to trigger the service worker update flow.

如果一个文件的哈希值发生变化,就足以确保 Service Worker 生成的 JavaScript 文件发生sw-precache变化。反过来,这足以触发 Service Worker 更新流程。

If you're not seeing an update flow triggered while testing things out, then it may be due to the service worker JavaScript file being served with HTTP caching headers that cause it to be fetched from the browser's cache rather than the from the network.

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

See https://stackoverflow.com/a/38854905/385997for a discussion of how HTTP caching headers come into play, and the best practices with regards to that.

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

回答by jcaruso

As the previous answers stated, there is a 1 day (24hr) built-in limit for the browser to look for updates to the service worker, but what you need to be mindful of is you still need to call .update()on your ServiceWorkerRegistrationobject otherwise the original version of the file will be used.

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

While testing changes in Chrome, I always right-click on the refresh button and select 'Empty Cache and Hard Reset' (options are available when developer tools are open) when working on my service worker script.

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

回答by Bitterjug

'sw-precache' has been superseded by Workboxwhich generates hashes for the files you want to precache and adds those to the source code of your service worker (I don't know if sw-precacheworks the same way, Jeff's answer suggests it does). If any of the files you want to precache change -- and you re-run your build -- the updated hashes in your service worker are updated which pretty much guarantees the service worker will be "at least one byte different".

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

When you reload (ctrl-r) or re-visit your app the browser will fetch again the service worker that was registered for it. And, if that service worker has changed, it will be "queued up" to manage the app. But it won't start managing the app until you close all tabs with the app open, and then open a new one.

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

When you hard refresh (shift-ctrl-r) it'll always load without a controllerwhich is not the same as using your new service worker.

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

For testing during development, I use skip waitingin devtools to make the new service worker replace the old one without waiting for me to close all the tabs.

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

回答by Yvert Evina

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);

});