我有一个服务工作程序,当缓存资源发生更改时,在获取期间发出Client.postMessage。我正在使用它来通知用户他们可能想要刷新。
我的问题是,当活动页面资源发生更改并且服务工作者发出该消息时,该页面尚未加载,因此没有javascript可以接收该消息。
是否有更好的方法来处理这样的情况,而不是使用waitUntil在发出消息之前暂停几秒钟?
另一种选择是从服务工作者写入IndexedDB,然后在第一次加载页面之前,在建立message
监听器之前读取它。
为简单起见,使用ibd-keyval
库,这可能看起来像:
// In your service worker:
importScripts('https://unpkg.com/[email protected]/idb-keyval.js');
async function notifyOfUpdates(urls) {
const clients = await self.clients.matchAll();
for (const client of clients) {
client.postMessage({
// Structure your message however you'd like:
type: 'update',
urls,
});
}
// Read whatever's currently saved in IDB...
const updatedURLsInIDB = await idb.get('updated-urls') || [];
// ...append to the end of the list...
updatedURLsInIDB.push(...urls);
// ...and write the updated list to IDB.
await idb.set('updated-urls', updatedURLsInIDB);
}
// In your web page:
<script src="https://unpkg.com/[email protected]/idb-keyval.js"></script>
<script>
async listenForUrlUpdates() {
const updatedURLsInIDB = await idb.get('updated-urls');
// Do something with updatedURLsInIDB...
// Clear out the list now that we've read it:
await idb.delete('updated-urls');
// Listen for ongoing updates:
navigator.serviceWorker.addEventListener('message', event => {
if (event.data.type === 'update') {
const updatedUrls = event.data.urls;
// Do something with updatedUrls
}
});
}
</script>