![](/img/trans.png)
[英]Does a service worker cache work site-wide, even without loading an HTML with sw.js?
[英]Service Worker is “installing” with every page reload though the sw.js did not change
我正在使用服务工作者来缓存Web应用程序的JS和CSS文件。 我主要使用谷歌Chrome示例中的代码,我唯一添加的是通知和倒计时,当“新的或更新的内容可用时”刷新窗口。
Google示例: https : //github.com/GoogleChrome/sw-precache/blob/5699e5d049235ef0f668e8e2aa3bf2646ba3872f/demo/app/js/service-worker-registration.js
然而,这种情况经常发生,我不明白为什么。 肯定没有对服务器上的文件进行任何更改,但有时我仍然看到通知和窗口重新加载。
我预计只有当服务工作者管理的任何文件实际发生变化时才会发生这种情况(它们都是通过Webpack进行散列并且两者之间肯定没有变化)。
这是我使用的代码,在index.html
内联:
/* eslint-env browser */
'use strict';
function reloadApp(delay) {
var t = delay || 0;
var message = 'New or updated content is available. Reloading app in {s} seconds';
var getMessage = function() { return message.replace('{s}', t) }
var div = document.createElement('div');
div.id = 'update-notification';
div.innerHTML = getMessage();
document.body.appendChild(div);
var intervalID = setInterval(function() {
t = t - 1;
if (t <= 0) {
clearInterval(intervalID);
window.location.reload();
}
else {
div.innerHTML = getMessage();
}
}, 1000);
}
if ('serviceWorker' in navigator && window.location.protocol === 'https:') {
navigator.serviceWorker.register('/service-worker.js').then(function(reg) {
console.info('serviceWorker registered');
reg.onupdatefound = function() {
var installingWorker = reg.installing;
installingWorker.onstatechange = function() {
switch (installingWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
reloadApp(5);
} else {
console.log('Content is now available offline!');
}
break;
case 'redundant':
console.error('The installing service worker became redundant.');
break;
}
};
};
}).catch(function(e) {
console.error('Error during service worker registration:', e);
});
}
这是我做的改变:
switch (installingWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and the fresh content will
// have been added to the cache.
// It's the perfect time to display a "New content is available; please refresh."
// message in the page's interface.
console.log('New or updated content is available.');
} else {
成为:
switch (installingWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
reloadApp(5);
服务工作者本身是通过sw-precache-webpack-plugin
,散列文件如下所示:
var precacheConfig = [["cms.CrudFactory.144344a2.js","6a65526f764f3caa4b8c6e0b84c1b31b"],["cms.routes.c20796b4.js","f8018476ceffa8b8f6ec00b297a6492d"],["common.cms-main.0f2db9ff.js","92017e838aff992e9f47f721cb07b6f0"],["common.licensing-main.8000b17d.js","0d43abd063567d5edaccdcf9c0e4c362"],["common.mediaplayer-main.314be5d2.js","2061501465a56e82d968d7998b9ac364"],["common.ordering-main.783e8605.js","0531c4a90a0fa9ea63fbe1f82e86f8c6"],["common.shared-main.0224b0ea.js","956ae4d2ddbddb09fb51804c09c83b22"],["common.stores-main.98246b60.js","cbdc46bc3abeac89f37e8f64b1737a22"],["component.App.284fec19.js","07f1923f1a0098bf9eba28fc7b307c18"],["component.AppToolbar.00e371de.js","9b542d4a85bdeece9d36ee4e389f6206"],["component.DevToolbar.652bf856.js","1744126e32774a93796146ac878ddd8e"],["component.Grid.4b964e52.js","755819ca2c7f911805e372401d638351"],["component.MediaPlayer.54db6e85.js","d0d8ae269665e810d1b997b473005f76"],["component.Search.05476f89.js","0cae8928aff533a6726dfaeb0661456a"],["data.country-list.d54f29a7.js","e27746418e02f75593a93b958a60807e"],["dev.sendSlackMessage.da8e22f4.js","ccb10829f18a727b79a5e8631bc4b2a2"],["index.html","02ff43eabc33c600e98785cffe7597d9"],["lib.gemini-scrollbar.df2fbf63.js","3941036bacb4a1432d22151ea7da073b"],["lib.isotope-horizontal.1604d974.js","6ac56d4296468c4428b5b5301a65938a"],["lib.isotope-packery.fabb73c3.js","808061641596e4b0ea2158b42d65915a"],["lib.react-color.265a6de0.js","f23f63d7e6934e381ffdc0405ecb449a"],["lib.react-date-picker.0a81fec3.js","778d1626645e439ad01e182ee589971a"],["lib.react-select.c768cf77.js","c8782991a161790ef2c9a2c7677da313"],["main.43e29bc6.js","fe6a6277acaa2a369ef235961be7bbcf"],["route.admin.CleanupPage.8b4bbf8e.js","8ab20412329e1ba4adc327713135be97"],["route.app.CmsPage.8a4303fb.js","0bf1506869db24bb9789c8a46449c8ad"],["route.app.CmsPageWrapper.accdebcc.js","c91e77aa8b518e1878761269deac22b6"],["route.app.ContactPage.75693d32.js","a530b00a5230a44897c2bf0aa9f402a8"],["route.app.PasswordResetExpiredDialog.65431bae.js","b5eef791dbd68edd4769bd6da022a857"],["route.app.SeriesDetailsPage.11a6989b.js","c52178b57767ae1bf94a9594cb32718e"],["route.cms.MetadataFormsPage.636188d2.js","e1e592b7e3dd82af774ac215524465c0"],["route.cms.PermissionsListPage.0e1e3075.js","9a3cc340a64238a1ab3ba1c0d483b7bd"],["route.cms.PermissionsPage.78a69f60.js","4b18e646715d6268e7aba3932f4e04a9"],["route.cms.SysconfigPage.f699b871.js","79bd1275213478f2ff1970e0b7341c49"],["styles.43e29bc620615f854714.css","b2e9e55e9ee2def2ae577ee1aaebda8f"],["styles.e0c12bb1c77e645e92d3.css","626778177949d72221e83b601c6c2c0f"],["translations.en.83fced0e.js","7e5509c23b5aafc1744a28a85c2950bb"],["translations.nl.4ae0b3bb.js","515ec7be7352a0c61e4aba99f0014a39"],["vendor.e0c12bb1.js","36ce9e0a59c7b4577b2ac4a637cb4238"]];
var cacheName = 'sw-precache-v3-nisv-client-' + (self.registration ? self.registration.scope : '');
问题:
case 'installed': if (navigator.serviceWorker.controller) {
是否正确case 'installed': if (navigator.serviceWorker.controller) {
意味着New or updated content is available
? 服务人员的生命周期 :
- registered
- installing
- installed
- waiting
- activated
- redundant
注册服务工作程序时,它是从服务器获取的,它在disk
缓存中的生命周期取决于Web服务器发送它的cache-control
响应头。
具有cache-control : no-store must-revalidate
被认为是最佳实践cache-control : no-store must-revalidate
以及max-age : 0
如果可能)。
如果您忘记了,服务工作者通常会在注册24小时后被认为是stale
的,并且会被refetched
并更新磁盘缓存。
您可以通过在服务工作者上升级cache
版本或更改服务工作者代码来进行手动升级。 即使是一个byte
变化使得浏览器view
服务工作者作为一个新的,并安装新的服务人员。
然而,这并不意味着旧的服务工作者被丢弃。 任何用户必须关闭所有选项卡/ 导航离开您的站点,浏览器要丢弃旧服务工作者,并激活新服务工作者。
您可以通过install handler
的self.skipWaiting
绕过此行为
那说,
开发时,您可以选择打开浏览器(铬)开发面板,导航到application
选项卡,然后选中显示的框
update on reload
这样做,无论您的服务工作者代码是否有变化, 立即丢弃旧服务工作者。
关于你的问题:
- 假设“安装”的情况是否正确:if(navigator.serviceWorker.controller){意味着新的或更新的内容是否可用?
没有。 这意味着,安装了新服务工作者,例如sw-v1,并且当前正在waiting
激活。
- 为什么“新的或更新的内容”案例经常发生?
你说,你正在使用sw-precache
。 因为,我自己没有使用它,我必须补充一个反问题
service-worker
的代码更改或缓存冲突? 如果是这样,那么,任何新版本的服务工作者必须只waiting
而不是activating
更改。
skipping
等待阶段的可能原因是,
install
事件中有一个self.skipWaiting
。 注意以上情况属实,仅限于
在这种情况下,您可能需要考虑注释掉self.skipWaiting
语句。 或者,也许你可以配置你的插件,不要跳过更新 - 这对你的内容很重要,你需要接听电话
代替您的资产更改和/或触发更新的事实,
其他(最可能的)原因必须是,
您在开发控制台上的application
- > service workers
选项卡下检查update on reload
框的update on reload
。
取消选中该框,如果选中,则清除所有缓存,取消注册所有工作人员。 之后,打开一个新选项卡并继续测试该行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.