navigator.serviceWorker.controller 始终为空

navigator.serviceWorker.controller is always null

我遇到的问题是,在注册 serviceWorker 后,navigator.serviceWorker.controller 始终为空。我从不强制刷新,只是刷新页面。我用 Google Chrome 42.0.2311.152 m(32 位)进行测试。

var currentServiceWorker = null;
navigator.serviceWorker.register(SERVICE_WORKER_URL).then(function(serviceWorkerRegistration { 
  if (navigator.serviceWorker.controller) {
    currentServiceWorker = navigator.serviceWorker.controller;
  } else {
    currentServiceWorker = serviceWorkerRegistration.active;
  }
});

据此:

The controller read-only property of the ServiceWorkerContainer interface returns a ServiceWorker object if its state is activated (the same object returned by ServiceWorkerRegistration.active). This property returns null if the request is a force refresh (Shift + refresh) or if there is no active worker. ( Source: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/controller)

navigator.serviceWorker.controller 应该 return 与 serviceWorkerRegistration.active 相同的对象。但是 .active 我得到了活跃的工人, .controller 没有。

你对这种情况有什么想法吗?

谢谢, 安迪

调试时我首先要看的是你当前所在的页面是否在服务工作者的范围内。如果你当前的页面不在范围内,那么它不会被控制(但你注册的 service worker 仍然可以被认为是活跃的)。

您正在调用 register(SERVICE_WORKER_URL),默认情况下,它将使用包含您的服务工作者脚本的目录作为范围。这通常是您想要的,但您需要确保 SERVICE_WORKER_URL 指的是位于您网站根目录的脚本。这样,它将能够控制同一根级别的页面,或您的 Web 根目录下目录中的页面。因此,如果您的 service worker JavaScript 文件当前位于 /scripts/ 子目录或类似目录下,请将其移至根目录。

您可以通过访问 chrome://serviceworker-internals/ 并查看与您的注册关联的范围是什么来检查服务工作者的当前范围。

navigator.serviceWorker.register只注册serviceworker并激活。但是要控制 serviceworker,您需要将 serviceworker 放在 public 根文件夹中,以便所有页面都在范围内,service worker 将附加到它。

尝试在服务工作者中添加:

self.addEventListener('activate', event => {
    clients.claim();
    console.log('Ready!');
});

clients.claim() 答案为我完成了,连同控制器更改了监听器:

navigator.serviceWorker.addEventListener("controllerchange", (evt) => {
    console.log("controller changed");
    this.controller = navigator.serviceWorker.controller;
});

谢谢 Kushagra Gour

确保在开发者工具 > 应用程序 > 服务工作者下未选中“绕过网络”。这将阻止您的服务工作者控制器被设置。