简体   繁体   English

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

[英]How to read Client.postMessage before the page loaded?

I have a service worker that emits Client.postMessage during fetch when a cached resource has changed. 我有一个服务工作程序,当缓存资源发生更改时,在获取期间发出Client.postMessage。 I'm using this to notify the user that they might want to refresh. 我正在使用它来通知用户他们可能想要刷新。

My problem is that when the active page resource is changed and the service worker emits that message, the page hasn't loaded yet so no javascript can receive the message. 我的问题是,当活动页面资源发生更改并且服务工作者发出该消息时,该页面尚未加载,因此没有javascript可以接收该消息。

Is there a better way to handle cases like this rather than using waitUntil to pause a few seconds before emitting the message? 是否有更好的方法来处理这样的情况,而不是使用waitUntil在发出消息之前暂停几秒钟?

Another option would be to write to IndexedDB from the service worker, and then read it when the page loads for the first time, before you establish your message listener. 另一种选择是从服务工作者写入IndexedDB,然后在建立message监听器之前第一次加载页面时读取它。

Using the ibd-keyval library for simplicity's sake, this could look like: 为简单起见,使用ibd-keyval库,这可能如下所示:

// In your service worker:
importScripts('https://unpkg.com/idb-keyval@2.3.0/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/idb-keyval@2.3.0/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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM