【问题标题】:Service Worker controllerchange never firesService Worker controllerchange 永远不会触发
【发布时间】:2016-10-20 18:02:17
【问题描述】:

我想在每次页面加载时向服务人员发送一条消息。

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

我如何知道何时可以开始向服务人员发送消息?

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

【问题讨论】:

    标签: javascript service-worker


    【解决方案1】:

    我如何知道何时可以开始向服务人员发送消息?

    只关注那一点:我推荐以下方法,它利用了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 事件侦听器没有触发,我的猜测是您没有在服务人员的 activate 事件中使用 clients.claim(),这意味着新激活的 Service Worker 不会控制当前页面。

    【讨论】:

    • 对我来说 navigator.serviceWorker.oncontrollerchangenavigator.serviceWorker.ready 直到我清理了存储,关闭标签并再次打开它才被解雇。只是重新加载页面没有帮助。听从这家伙的建议:stackoverflow.com/questions/29874068/…
    • 我注意到了一件有趣的事情。如果您在 navigator.serviceWorker.ready 解析时立即发出请求,则 SW 不会捕获这些请求,但如果您使用 navigator.serviceWorker.oncontrollerchange 进行请求,则 SW 会捕获这些请求。通过附加body 脚本标签进行检查。
    • 我正在使用clients.claim 但仍然无法正常工作,我已经尝试过您的方法但仍然没有。有趣的是它一直工作到昨天......
    【解决方案2】:

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

    使用navigator.serviceWorker.ready 承诺,一旦检测到活动的 Service Worker,无论何时安装/激活,它都会立即解决。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-15
      • 2021-05-22
      • 2015-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多