【问题标题】:navigator.serviceWorker.controller is null until page refreshnavigator.serviceWorker.controller 在页面刷新之前为空
【发布时间】:2019-12-02 03:22:16
【问题描述】:

我使用 angularjs 并使用 service worker 来接收推送通知。 但是 navigator.serviceWorker.controller 在页面刷新之前为空,我不知道如何解决这个问题

serviceworker 的一些代码:

self.addEventListener('push', pwServiceWorker.pushReceived);
self.addEventListener('notificationclick', pwServiceWorker.notificationClicked);

// refresh caches
self.addEventListener('activate', function (event)
{
    event.waitUntil(
        caches.keys().then(function (cacheNames)
        {
            return Promise.all(
                cacheNames.map(function (cacheName)
                {
                    return caches.delete(cacheName);
                })
            );
        })
    );
});

并在收到推送时向 serviceworker 中的客户端发送消息:

self.clients.matchAll().then(function(all) {
    console.log(all);
    all.forEach(function(client) {
        client.postMessage(data);
    });
});

在 mainController.js 中给出这样的消息:

 if (!navigator.serviceWorker || !navigator.serviceWorker.register) {
        console.log("This browser doesn't support service workers");
        return;
    }

    // Listen to messages from service workers.
    navigator.serviceWorker.addEventListener('message', function(event) {
        console.log("Got reply from service worker: " + event.data);
    });

    // Are we being controlled?
    if (navigator.serviceWorker.controller) {
        // Yes, send our controller a message.
        console.log("Sending 'hi' to controller");
        navigator.serviceWorker.controller.postMessage("hi");
    } else {
        // No, register a service worker to control pages like us.
        // Note that it won't control this instance of this page, it only takes effect
        // for pages in its scope loaded *after* it's installed.
        navigator.serviceWorker.register("service-worker.js")
            .then(function(registration) {
                console.log("Service worker registered, scope: " + registration.scope);
                console.log("Refresh the page to talk to it.");
                // If we want to, we might do `location.reload();` so that we'd be controlled by it
            })
            .catch(function(error) {
                console.log("Service worker registration failed: " + error.message);
            });
    }

【问题讨论】:

标签: javascript angularjs service-worker


【解决方案1】:

这是预期的行为。要在不等待刷新/重新打开的情况下控制所有打开的页面,您必须将这些命令添加到您的 Service Worker:

self.addEventListener('install', function(event) {
    event.waitUntil(self.skipWaiting()); // Activate worker immediately
});

self.addEventListener('activate', function(event) {
    event.waitUntil(self.clients.claim()); // Become available to all pages
});

您可以在skipWaiting() docs 和clients.claim() docs 中了解更多信息。

【讨论】:

  • 这些event.waitUntil(... 函数是除了缓存函数之外(参见原始问题)还是替换它们?如果更换它们,它们什么时候使用?
  • I found this snippet 将它们用作对我来说非常有效的回调。
  • 我要注意的另一点是shift+reload will bypass the service worker 和窗口将不受控制!
  • 我的服务工作者中有这些行,并且 navigator.serviceWorker.controller 在重新加载页面之前仍然为空。一定还有其他事情要做
【解决方案2】:

确保您的 service worker 的范围包括有问题的 url。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    相关资源
    最近更新 更多