Javascript 如何:ServiceWorker检查是否准备好更新
我正在努力实现的目标:Javascript 如何:ServiceWorker检查是否准备好更新,javascript,service-worker,sw-precache,Javascript,Service Worker,Sw Precache,我正在努力实现的目标: 使用加载程序/微调器呈现页面 如果service worker.js已注册并处于活动状态,则检查更新 如果没有更新,则删除加载程序 如果updatefound并安装了新版本,则重新加载页面 else registerservice worker.js 当updatefound表示安装了新的加载程序时,请删除加载程序 我正在使用sw precache模块生成service worker.js和以下注册码: window.addEventListener('loa
- 使用加载程序/微调器呈现页面
- 如果
已注册并处于活动状态,则检查更新service worker.js
- 如果没有更新,则删除加载程序
- 如果
并安装了新版本,则重新加载页面updatefound
- else register
service worker.js
- 当
表示安装了新的加载程序时,请删除加载程序updatefound
- 当
sw precache
模块生成service worker.js
和以下注册码:
window.addEventListener('load', function() {
// show loader
addLoader();
navigator.serviceWorker.register('service-worker.js')
.then(function(swRegistration) {
// react to changes in `service-worker.js`
swRegistration.onupdatefound = function() {
var installingWorker = swRegistration.installing;
installingWorker.onstatechange = function() {
if(installingWorker.state === 'installed' && navigator.serviceWorker.controller){
// updated content installed
window.location.reload();
} else if (installingWorker.state === 'installed'){
// new sw registered and content cached
removeLoader();
}
};
}
if(swRegistration.active){
// here I know that `service-worker.js` was already installed
// but not sure it there are changes
// If there are no changes it is the last thing I can check
// AFAIK no events are fired afterwards
}
})
.catch(function(e) {
console.error('Error during service worker registration:', e);
});
});
阅读后,很明显没有类似于updatenotfound
的处理程序。看起来像是serviceWorker.register
检查service worker.js
是否通过运行在内部进行了更改,但我看不到通过公共api公开的类似方法
我认为我的选择是:
- 服务人员注册激活后等待几秒钟,查看是否触发了
onUpdate-Found
- 如果缓存未更新,则从
code触发自定义事件service worker.js
编辑: 我提出了一些代码,通过在软件注册和软件客户端之间使用
postMessage()
解决了这个问题(正如@pate所建议的)
下面的演示试图在软件客户端和软件注册之间通过postMessage
实现检查,但由于软件代码已被缓存而失败
编辑: 所以现在看来我无法实现我想要的,因为:
onupdatefound
,没有其他任何东西会通知软件的更改旧软件的激活
先于onupdatefound
激活后不会触发任何内容
从Chrome 46开始,update()返回一个承诺,如果操作成功完成或没有更新,该承诺将以“未定义”解决
我脑海中闪现的唯一方法是正常启动加载程序,然后在service worker的安装功能中将其删除。我将在您的service-worker.js中尝试一下:
self.addEventListener('install', function(e) {
console.log('[ServiceWorker] Install');
e.waitUntil(
caches.open(cacheName).then(function(cache) {
console.log('[ServiceWorker] Caching app shell');
return cache.addAll(filesToCache);
}).then(function() {
***removeLoader();***
return self.skipWaiting();
})
);
});
法比奥提供的另一个答案不起作用。服务工作者脚本无法访问DOM。不可能从DOM中删除任何内容,例如,从服务工作者内部操作处理DOM元素的任何数据。该脚本单独运行,没有共享状态 不过,您可以做的是在实际运行JS的页面和服务工作者之间发送消息。我不确定这是否是实现OP要求的最好方法,但可以用来实现它
我希望我能清楚地解释我的想法:)很好的建议,我用一个被黑客破解的解决方案做了一次尝试。现在我将等待更多的回复。是的,我并没有声称提供完整的程序,只是提供了概念。当我写removeLoader()时;在软件脚本中,我的意思是必须在那里做一些事情(一条消息?一个事件检查?)。一个警告是,如果软件还没有注册(第一次安装),它是可以的,但是如果它是,那么事件将从已经激活的软件中触发,并且它会说没有任何更改。因此,您似乎无法保证在收到这些信息后不会触发
onUpdate-Found
。看起来应该可以解决问题,但只有在工作人员发生更改时才会触发此事件。您好,您对此有任何更新吗?事实上,我没有,生产中的应用程序在初始加载(视图渲染)发生并随后检测到更改后会进行这种疯狂的刷新。谢谢您的回答