Jov*_*sic 7 javascript service-worker
我正在使用 Service Worker 来缓存 Web 应用程序的 JS 和 CSS 文件。我主要使用 Google Chrome 示例中的代码,我添加的唯一内容是当“新的或更新的内容可用”时刷新窗口的通知和倒计时。
然而,这种情况经常发生,我不明白为什么。服务器上的文件肯定没有任何更改,但有时我仍然会看到通知和窗口重新加载。
我预计只有当服务工作人员管理的任何文件实际发生更改时才会发生这种情况(它们都通过 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);
});
}
Run Code Online (Sandbox Code Playgroud)
这是我所做的改变:
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 {
Run Code Online (Sandbox Code Playgroud)
变成:
switch (installingWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
reloadApp(5);
Run Code Online (Sandbox Code Playgroud)
Service Worker 本身是通过生成的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 : '');
Run Code Online (Sandbox Code Playgroud)
问题:
case 'installed': if (navigator.serviceWorker.controller) {这意味着假设正确吗New or updated content is available? Service Worker 有一个生命周期:
- registered
- installing
- installed
- waiting
- activated
- redundant
Run Code Online (Sandbox Code Playgroud)
当您注册 Service Worker 时,它会从服务器获取,并且它在缓存中的生命周期disk取决于cache-control您的 Web 服务器发送它的响应标头。
如果可能的话,最好的做法是使用 acache-control : no-store must-revalidate和 a max-age : 0。
stale如果您忘记了,通常会在注册 24 小时后考虑 Service Worker ,refetched并更新磁盘缓存。
您可以通过在 Service Worker 上升级版本或更改 Service Worker 代码来进行手动升级。cache即使byte发生更改也会使浏览器view成为新的 Service Worker,并且它会安装新的 Service Worker。
然而,这并不意味着旧的 Service Worker 被丢弃。任何用户都必须关闭所有选项卡/离开您的站点,以便浏览器丢弃旧的 Service Worker 并激活新的 Service Worker。
您可以通过self.skipWaiting在您的install handler
也就是说,
在开发时,您可以选择打开浏览器的(chromium)开发面板,导航到选项application卡,然后选中显示的框
update on reload
这样做的作用是,立即丢弃旧的 Service Worker,无论您的 Service Worker 代码是否有更改。
关于您的问题:
- “已安装”情况的假设是否正确: if (navigator.serviceWorker.controller) { 表示有新的或更新的内容可用?
不。这意味着新的 Service Worker(例如 sw-v1)已安装,并且当前正在waiting激活。
- 为什么“新内容或更新内容”的情况如此频繁地发生?
你说,你正在使用sw-precache. 因为我自己没有用过,所以我必须补充一个反问
service-worker?如果是这样,那么您的 Service Worker 的任何新版本都只能是变化waiting而不是activating变化。
skipping等待阶段的可能原因是,
self.skipWaiting内部install。请注意,上述内容为真,仅当
在这种情况下,您可能需要考虑注释掉该self.skipWaiting语句。或者,也许您可以配置您的插件,不要跳过更新 - 这对您的内容很重要,您需要接听电话
代替您的资产发生更改和/或触发更新的事实,
另一个(最可能的)原因必须是,
您在开发控制台的->选项卡update on reload下选中了一个框。applicationservice workers
取消选中该框(如果选中),然后清除所有缓存,取消注册所有工作人员。之后,打开一个新选项卡并继续测试行为。
| 归档时间: |
|
| 查看次数: |
2778 次 |
| 最近记录: |