Service Worker controllerchange 永远不会触发

Service Worker controllerchange never fires

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

第一次加载页面时,它调用 register(),然后在 navigator.serviceWorker 上侦听 "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);
});

How do I know when I can start postMessaging a 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 中使用 clients.claim() activate事件,表示新激活的service worker不会控制当前页面。

它没有触发的原因是因为您正在注册 controllerchange 事件 Service Worker 已经 installed/activated 之后。因此,此事件将为 new Service Worker 触发,例如使用 skipWaiting() 的那些。但不适用于最初的 Service Worker。

使用 navigator.serviceWorker.ready 承诺,一旦检测到活动的 Service Worker 就会立即解决,无论它是什么时候installed/activated。