如何在页面加载之前读取Client.postMessage?

问题描述 投票:4回答:1

我有一个服务工作程序,当缓存资源发生更改时,在获取期间发出Client.postMessage。我正在使用它来通知用户他们可能想要刷新。

我的问题是,当活动页面资源发生更改并且服务工作者发出该消息时,该页面尚未加载,因此没有javascript可以接收该消息。

是否有更好的方法来处理这样的情况,而不是使用waitUntil在发出消息之前暂停几秒钟?

javascript service-worker
1个回答
4
投票

另一种选择是从服务工作者写入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>
© www.soinside.com 2019 - 2024. All rights reserved.