navigator.serviceWorker永远不会准备好

Lar*_*y K 39 service-worker

我成功注册了一个服务工作者,但接着是代码

navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    // Do we already have a push message subscription?
    ....
Run Code Online (Sandbox Code Playgroud)

挂起 - 永远不会调用该函数.为什么?

Lar*_*y K 73

问题是service-worker.js文件存储在assets子目录中.

不要这样做:将service-worker.js存储在root of your app(或更高版本)中.这样您的应用就可以访问服务工作者.

请参阅HTML5Rocks文章 -

register方法的一个细微之处在于服务工作文件位置.在这种情况下,您会注意到服务工作者文件位于域的根目录下.这意味着服务工作者的范围将是整个起源.换句话说,此服务工作者将接收此域上所有内容的获取事件.如果我们在/example/sw.js注册服务工作者文件,那么服务工作者只会看到URL以/ example /开头的页面的获取事件(即/ example/page1 /,/ example/page2 /).

添加

一个新问题是,如果页面被硬重新加载,那么服务工作者就永远不会准备好.后续软页面重新加载工作正常.谷歌自己的示例代码失败了.查看Chrome错误报告.

修复程序包含在Chrome 44中.

  • 对我来说这是超级跛脚:不得不关闭浏览器的标签("Chrome")并再次打开它.清除缓存存储,浏览器缓存和取消注册服务工作者无效. (13认同)
  • 非常感谢.我已经在灌木丛中殴打了两天,而我所要做的就是将sw.js从脚本移动到root ... (4认同)
  • 我敲了几个小时,直到看到这个:D (3认同)

Tri*_*IER 5

就像在接受的答案中所说的那样,问题确实可能是因为您的服务工作者 JS 文件与您当前的页面位于不同的路径中。

默认情况下,service worker 的作用域是其 JS 文件的路径。如果你的JS文件是可到达http://www.example.com/assets/js/service-worker.js,您的服务人员只会工作/“做好准备”为开头的网址/assets/js/

但是,您可以更改 Service Worker 的范围。首先,如果使用该scope选项,您需要注册:

navigator.serviceWorker.register('http://www.example.com/assets/js/service-worker.js', {
    scope: '/',
});
Run Code Online (Sandbox Code Playgroud)

如果你这样做了,就这样,你会在 Chrome 控制台中得到错误:

提供的范围 ('/') 的路径不在允许的最大范围 ('/assets/js/') 之下。调整范围,移动 Service Worker 脚本,或使用 Service-Worker-Allowed HTTP 标头来允许范围。

/admin/#/builder:1 Uncaught (in promise) DOMException: Failed to register a ServiceWorker for scope (' http://www.example.com/ ') with script

(' http://www.example.com/assets/js/service-worker.js '): 提供的范围 ('/') 的路径不在允许的最大范围 ('/assets/js/' )。调整范围,移动 Service Worker 脚本,或使用 Service-Worker-Allowed HTTP 标头来允许范围。

然后,您需要.htacess在网站的根目录下创建一个包含以下内容的文件:

<IfModule mod_headers.c>
    <Files ~ "service-worker\.js">
        Header set Service-Worker-Allowed: /
    </Files>
</IfModule>
Run Code Online (Sandbox Code Playgroud)