Service Worker controllerchange永远不会触发

Service Worker controllerchange never fires

本文关键字:永远 Worker controllerchange Service      更新时间:2023-09-26

我想在每次页面加载时发送一个消息给service worker。

第一次加载页面时,它调用register(),然后监听navigator上的"controllerchange"事件。但它永远不会触发。

我怎么知道什么时候可以开始向service worker发送消息?

navigator.serviceWorker.register(swURL).then(function(){
    var sw;
    if (navigator.serviceWorker.controller) {
        sw = navigator.serviceWorker.controller;
        sw.postMessage('ping');
        return;
    }
    function onchange(){
        sw = navigator.serviceWorker.controller;
        sw.postMessage('ping');
        navigator.serviceWorker.removeEventListener('controllerchange', onchange);
    }
    navigator.serviceWorker.addEventListener('controllerchange', onchange);
}).catch(function(err) {
    // registration failed :(
    console.log('ServiceWorker registration failed: ', err);
});

我怎么知道什么时候可以开始向service worker发送消息?

只关注这一点:我推荐以下方法,它利用了navigator.serviceWorker.ready承诺:

// navigator.serviceWorker.ready can be used from anywhere in your
// page's JavaScript, at any time.
// It will wait until there's an active service worker, 
// and then resolve with the service worker registration
navigator.serviceWorker.ready.then(registration => {
  registration.active.postMessage('ping');
});

如果你真的想知道为什么你的controllerchange事件监听器没有被触发,我的猜测是你没有在你的service worker的activate事件中使用clients.claim(),这意味着新激活的service worker不会控制当前页面。

没有触发的原因是你在 Service Worker已经安装/激活之后注册了controllerchange事件。所以这个事件将触发new Service worker,例如使用skipWaiting()的Service worker。但对初始Service Worker来说不是这样。

使用navigator.serviceWorker.ready promise,一旦检测到活动的Service Worker,它就会解析,无论它是什么时候安装/激活的