最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Service Worker controllerchange never fires - Stack Overflow

programmeradmin4浏览0评论

I want to send a message to a service worker every time the page loads.

The first time the page loads it calls register() and then listens for the "controllerchange" event on navigator.serviceWorker but this never fires.

How do I know when I can start postMessaging a 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);
});

I want to send a message to a service worker every time the page loads.

The first time the page loads it calls register() and then listens for the "controllerchange" event on navigator.serviceWorker but this never fires.

How do I know when I can start postMessaging a 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);
});
Share Improve this question edited Oct 20, 2016 at 18:29 Damian 2,8502 gold badges30 silver badges30 bronze badges asked Oct 20, 2016 at 18:02 Matthew PhillipsMatthew Phillips 1121 silver badge11 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

How do I know when I can start postMessaging a service worker?

Just focusing on that bit: I'd remend the following approach, which makes use of the navigator.serviceWorker.ready promise:

// 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');
});

If you do want to get to the bottom of why your controllerchange event listener isn't firing, my guess would be that you're not using clients.claim() in your service worker's activate event, which means the newly-activated service worker won't take control of the current page.

The reason it's not firing is because you are registering the controllerchange event after the Service Worker has already installed/activated. So this event will fire for new Service Workers, e.g. ones that use skipWaiting(). But not for the initial Service Worker.

Use navigator.serviceWorker.ready promise which resolves as soon as there is an active Service Worker detected, no matter when it was installed/activated.

发布评论

评论列表(0)

  1. 暂无评论