【问题标题】:How do I clear service worker caches when unregistering?注销时如何清除服务人员缓存?
【发布时间】:2018-05-01 16:51:27
【问题描述】:

热门问题How do I uninstall a Service Worker? 为使用 JavaScript 取消注册服务工作者提供了一个很好的答案。如何让服务人员在注销时清除任何命名缓存?

来自 MDN unregisterService Worker 将在取消注册之前完成所有正在进行的操作。因此,听起来应该可以监听 uninstall 事件,但没有这样事件存在as far as I can tell。对于傻笑,我尝试将self.addEventListener('uninstall', ...) 添加到服务人员,但正如预期的那样,它没有在取消注册时触发。我还尝试收听任何可能在取消注册时发送的message...没有骰子。

我也考虑观看service worker state,但installinginstalledactivatingactivatedredundant 似乎都不相关。更不用说,看起来消息传递给服务工作者是不可能的,所以我不确定我会如何处理来自服务工作者外部的uninstalling 状态。

伸手去拿吸管,虽然我看到了对 uninstalling flag 的引用,但我还没有看到它暴露在任何地方。有什么建议吗?

【问题讨论】:

    标签: service-worker


    【解决方案1】:

    以下代码应取消注册所有服务工作者并清除缓存存储 API 中的所有内容:

    async function unregisterAndClearCaches() {
      const registrations = await navigator.serviceWorker.getRegistrations();
      const unregisterPromises = registrations.map(registration => registration.unregister());
    
      const allCaches = await caches.keys();
      const cacheDeletionPromises = allCaches.map(cache => caches.delete(cache));
    
      await Promise.all([...unregisterPromises, ...cacheDeletionPromises]);
    }
    

    使用Clear-Site-Data header 是在单个操作中“强制”清除所有内容(服务工作者注册、缓存等)的另一种选择。

    【讨论】:

    • 啊,就是这么简单!我一直在想,由服务工作者创建的缓存仅供该服务工作者使用。我可以为我想要删除的每个缓存(不一定是所有缓存)调用caches.delete('cache_name'),同时在服务工作者上调用unregister。谢谢!
    【解决方案2】:

    这可以通过消息传递来完成。我更喜欢 Jeff Posnick 的回答的一个原因是缓存的名称不需要在服务工作者之外知道。在 service worker 中,添加消息监听器:

    self.addEventListener('message', (event) => {
        messageHandler(event);
    });
    

    messageHandler() 然后可以对各种传递的消息采取行动。例如:

    function messageHandler(event) {
        if (event.data === 'purge_cache') {
            caches.delete('mycache')
            .then((success) => {
                console.log("Cache removal status: " + success);
            })
            .catch((err) => {
                console.log("Cache removal error: ", err);
            });
        }
    }
    

    要触发此操作,请将脚本中的消息发布到服务工作者范围内的页面上。因此,对于如何删除缓存然后注销服务工作者的原始问题,您可以这样做:

    navigator.serviceWorker.getRegistration()
    .then((registration) => {
        registration.active.postMessage('purge_cache');
        registration.unregister()
        .then((success) => {
            console.log('Service worker unregistration status: ' + success);
        })
        .catch((err) => {
            console.log('Service worker unregistration failed', err);
        });
    })
    .catch((err) => {
        console.log('Service worker registration not found.');
    });
    

    注意,我没有等待postMessage('purge_cache')的成功回复;来自 MDN unregister,“Service Worker 将在未注册之前完成所有正在进行的操作。”

    【讨论】:

    • 这应该是答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 2022-07-30
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多