在此链接https://github.com/deanhume/pwa-update-available之后,我正在尝试实施服务工作者更新,但是我遇到的问题是未触发事件更新,我认为这与我的应用程序设计有关,基本上是SPA ,表示我一直在index.html上,其行为类似于app-shell,并且我会根据单击哪个按钮将内容推入内容区域。
只有其他页面是login / index.html
app.js安装/更新服务工作者的内容如下:
let newWorker;
function showUpdateBar() {
let snackbar = document.getElementById('snackbar');
snackbar.className = 'show';
}
// The click event on the pop up notification
document.getElementById('reload').addEventListener('click', function(){
newWorker.postMessage({ action: 'skipWaiting' });
});
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/pwa/sw.js').then(reg => {
console.log( 'ServiceWorker registration successful with scope: ', registration.scope );
reg.addEventListener('updatefound', () => {
// A wild service worker has appeared in reg.installing!
newWorker = reg.installing;
newWorker.addEventListener('statechange', () => {
// Has network.state changed?
switch (newWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
// new update available
showUpdateBar();
}
// No update available
break;
}
});
});
});
let refreshing;
navigator.serviceWorker.addEventListener('controllerchange', function () {
if (refreshing) return;
window.location.reload();
refreshing = true;
});
}
和sw.js文件内容如下:
var cacheName = 'v28';
self.addEventListener('install', event => {
event.waitUntil(
caches.open(cacheName)
.then(cache => cache.addAll([
"/pwa/index.html",
"/pwa/main.css",
"/pwa/js/app/app.js",
"/pwa/js/app/libs/api.js",
'/pwa/query.js',
'/pwa/js/libs/localforage.min.js',
'/pwa/js/libs/utils.js'
]))
);
});
self.addEventListener('message', function (event) {
if (event.data.action === 'skipWaiting') {
self.skipWaiting();
}
});
// Allow sw to control of current page
self.addEventListener('activate', event => {
console.log('Activating new service worker...');
const cacheWhitelist = [cacheName];
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheWhitelist.indexOf(cacheName) === -1) {
return caches.delete(cacheName);
}
})
);
})
);
});
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request)
.then(function (response) {
if (response) {
return response;
}
return fetch(event.request);
})
);
});
index.html的部分内容:
<div id="snackbar">A new version of this app is available. Click <a id="reload">here</a> to update.</div>
因此,基本上,我所面临的问题是触发更新,当我将版本号从v28更改为v29并重新加载页面时,我得到了提示,但是即使注销,我也没有得到提示,登录或退出,然后重新打开应用。
我该如何解决?
注意:PWA是我的渐进式应用程序文件夹,我使用php / yii2作为后端,而不使用节点服务器或其他JS框架。
答案 0 :(得分:1)
只有在将index.html加载到浏览器中时,您才会触发服务工作者注册例程。这是唯一执行代码的时间。
除非您定期轮询服务器或可能打开一个websocket(为此花费很多),否则您将不知道是否有新的服务人员可用。您可能会让用户注册推送通知。。。为此感到头疼。
因此,每隔几个小时或几天将服务器池化一次以进行更新。
如果有更新,则可以触发更新例程。
我会将轮询逻辑放入实际的服务工作者代码中,以使其脱离UI,如果您是SPA,则您已经将UI线程锁定了足够的LOL。
当服务人员从休眠状态唤醒时,有很多方法可以为这只猫设置皮肤setTimeout(...,{lots of seconds})。
如果您可以发出HEAD请求,以将网络流量保持在最低水平。
如果有更新,则可以将消息发布到UI以更新服务工作者。
这不是我所说的普通代码。我做了类似的事情来使我的缓存资产保持最新,所以我去过那里:)