PWA Service worker 缓存/更新预期行为
PWA Service worker caching / updating expected behaviour
我正在尝试为 Ionic Angular 应用程序缓存 service worker。
我的目标是弹出警报:"New update available, click to reload the app",
我相信我已经根据我的阅读遵循了所有正确的做法,但是我遗漏了一些东西,因为我无法可靠地让警报在更新后弹出。它会弹出,但最多可能需要 24 小时 - 这是预期的行为吗?
我正在使用四个文件:
- service-worker.js
- index.html
- myapp.page.ts
- .htaccess
在service-worker.js 我:
- 命名缓存
- 设置一个CACHE_VERSION更新时使用
- 使用工具箱设置network/cache优先级
。
'use strict';
importScripts('./build/sw-toolbox.js');
self.toolbox.options.cache = {
name: 'my-cache'
};
const CACHE_VERSION = 1;
self.toolbox.router.get('assets/*', self.toolbox.cacheFirst);
self.toolbox.router.get('build/*', self.toolbox.networkFirst);
self.toolbox.router.get('/', self.toolbox.networkFirst);
self.toolbox.router.get('manifest.json', self.toolbox.networkFirst);
在index.html我:
- 创建一个承诺,这样我们就可以从 myapp.page.ts
连接到 service worker 的 onupdatefound
.
<script>
// make the whole serviceworker process into a promise so later on we can
// listen to it and in case new content is available a toast will be shown
window.isUpdateAvailable = new Promise(function(resolve, reject) {
// checks if serviceWorker is supported and disable service workers while developing
if ('serviceWorker' in navigator && ['localhost', '127'].indexOf(location.hostname) === -1) {
// register service worker file
navigator.serviceWorker.register('service-worker.js')
.then(reg => {
reg.onupdatefound = () => {
const installingWorker = reg.installing;
installingWorker.onstatechange = () => {
switch (installingWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
// new update available
console.log("new update available");
resolve(true);
} else {
// no update available
resolve(false);
console.log("up to date");
}
break;
}
};
};
})
.catch(err => console.error('[SW ERROR]', err));
}
});
</script>
在 myapp.page.ts 我关注了这篇文章:https://medium.com/progressive-web-apps/pwa-create-a-new-update-available-notification-using-service-workers-18be9168d717:
- 听听我们在index.html
中创造的承诺
- 弹出警报
- 当用户点击重新加载时删除缓存并重新加载页面
。
public ngOnInit () {
// listen to the service worker promise in index.html to see if there has been a new update.
// condition: the service-worker.js needs to have some kind of change - e.g. increment CACHE_VERSION.
window['isUpdateAvailable']
.then(isAvailable => {
if (isAvailable) {
console.log('Update is available');
const alert = this.alertController.create({
title: 'New Update available!',
message: 'Please reload the app to continue.',
buttons: [
{
text: 'Reload',
handler: () => {
caches.delete("my-cache");
location.reload(true);
}
}]
});
alert.present();
}
});
}
在 .htaccess 中:
- 为 service-worker.js 设置 headers,使其不被缓存:
。
<Files service-worker.js>
<IfModule mod_headers.c>
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires 0
</IfModule>
</Files>
然后我增加 const CACHE_VERSION 值以引起 service-worker.js 文件中的更改。
我的期望是,当我将 CACHE_VERSION 和 return 增加到应用程序的已打开版本(选项卡)或打开应用程序的新选项卡时,它应该弹出警报或至少控制台日志显示有更新。这不会立即发生,而是可能需要一天的时间才会发生。
这是预期的行为还是我遗漏了什么?谢谢!
Service Worker 在页面重新加载之前不会更新。
要使其在用户不重新加载页面的情况下更新服务工作者,您可以使用服务工作者的 update() 方法:
https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/update
例如每半小时检查一次新的 service worker:
setInterval(() => {
console.log("force check our service-worker from the server")
reg.update();
}, 1800000);
我正在尝试为 Ionic Angular 应用程序缓存 service worker。
我的目标是弹出警报:"New update available, click to reload the app",
我相信我已经根据我的阅读遵循了所有正确的做法,但是我遗漏了一些东西,因为我无法可靠地让警报在更新后弹出。它会弹出,但最多可能需要 24 小时 - 这是预期的行为吗?
我正在使用四个文件:
- service-worker.js
- index.html
- myapp.page.ts
- .htaccess
在service-worker.js 我:
- 命名缓存
- 设置一个CACHE_VERSION更新时使用
- 使用工具箱设置network/cache优先级
。
'use strict';
importScripts('./build/sw-toolbox.js');
self.toolbox.options.cache = {
name: 'my-cache'
};
const CACHE_VERSION = 1;
self.toolbox.router.get('assets/*', self.toolbox.cacheFirst);
self.toolbox.router.get('build/*', self.toolbox.networkFirst);
self.toolbox.router.get('/', self.toolbox.networkFirst);
self.toolbox.router.get('manifest.json', self.toolbox.networkFirst);
在index.html我:
- 创建一个承诺,这样我们就可以从 myapp.page.ts 连接到 service worker 的 onupdatefound
.
<script>
// make the whole serviceworker process into a promise so later on we can
// listen to it and in case new content is available a toast will be shown
window.isUpdateAvailable = new Promise(function(resolve, reject) {
// checks if serviceWorker is supported and disable service workers while developing
if ('serviceWorker' in navigator && ['localhost', '127'].indexOf(location.hostname) === -1) {
// register service worker file
navigator.serviceWorker.register('service-worker.js')
.then(reg => {
reg.onupdatefound = () => {
const installingWorker = reg.installing;
installingWorker.onstatechange = () => {
switch (installingWorker.state) {
case 'installed':
if (navigator.serviceWorker.controller) {
// new update available
console.log("new update available");
resolve(true);
} else {
// no update available
resolve(false);
console.log("up to date");
}
break;
}
};
};
})
.catch(err => console.error('[SW ERROR]', err));
}
});
</script>
在 myapp.page.ts 我关注了这篇文章:https://medium.com/progressive-web-apps/pwa-create-a-new-update-available-notification-using-service-workers-18be9168d717:
- 听听我们在index.html 中创造的承诺
- 弹出警报
- 当用户点击重新加载时删除缓存并重新加载页面
。
public ngOnInit () {
// listen to the service worker promise in index.html to see if there has been a new update.
// condition: the service-worker.js needs to have some kind of change - e.g. increment CACHE_VERSION.
window['isUpdateAvailable']
.then(isAvailable => {
if (isAvailable) {
console.log('Update is available');
const alert = this.alertController.create({
title: 'New Update available!',
message: 'Please reload the app to continue.',
buttons: [
{
text: 'Reload',
handler: () => {
caches.delete("my-cache");
location.reload(true);
}
}]
});
alert.present();
}
});
}
在 .htaccess 中:
- 为 service-worker.js 设置 headers,使其不被缓存:
。
<Files service-worker.js>
<IfModule mod_headers.c>
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires 0
</IfModule>
</Files>
然后我增加 const CACHE_VERSION 值以引起 service-worker.js 文件中的更改。
我的期望是,当我将 CACHE_VERSION 和 return 增加到应用程序的已打开版本(选项卡)或打开应用程序的新选项卡时,它应该弹出警报或至少控制台日志显示有更新。这不会立即发生,而是可能需要一天的时间才会发生。
这是预期的行为还是我遗漏了什么?谢谢!
Service Worker 在页面重新加载之前不会更新。
要使其在用户不重新加载页面的情况下更新服务工作者,您可以使用服务工作者的 update() 方法: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/update
例如每半小时检查一次新的 service worker:
setInterval(() => {
console.log("force check our service-worker from the server")
reg.update();
}, 1800000);