首页 文章

如何防止同一服务工作者注册多个页面?

提问于
浏览
12

我有一个服务工作者脚本,它在多个站点级别上重复注册 .

换句话说,同一服务工作者在www.site.ca/,www.site.ca/text-text,www.site.ca/example-example等注册 .

该网站 Build 在PHP上,根据内容生成不同的网址,因此类似API . 服务工作者注册在这些页面上的原因是因为大多数站点流量落在这些页面而不是主页上 . 结果是同一服务工作者在不同页面上注册了不同的ID .

有没有人有办法防止多个子级别上的同一脚本多次注册?

编辑:

即使用户不在站点上,服务工作者的目的是设置通知 . 此外,我所遇到的问题会对将来更新服务工作者的任何尝试产生负面影响,因为要更新多个副本 . 结果是当用户在特定页面上再次登陆站点时,只有一个副本会被更新 . 无法保证该服务工作文件的所有副本都将得到更新 . 此外,多个副本的结果导致用户从站点获得通知堆栈,因此这是一个问题 .

编辑:

以下是我到目前为止的情况,我的理解范围定义了它的注册位置 . 然而问题是它需要能够在人进入站点的任何地方进行注册,因此范围被设置为“/” .

我想解决的问题是防止相同服务工作文件的后续寄存器 .

Localhost是实际站点的占位符 .

navigator.serviceWorker.register('localhost/service-worker.js', {scope: './'})
.then(initialiseState);

在用于调试的Chrome开发工具中,生成的服务工作者的格式如下:

范围:localhost / url / stuff /
注册ID:110
活跃的 Worker :
安装状态:已激活
运行状态:已停止
脚本:localhost / service-worker.js
...

范围:localhost /
注册ID:111
活跃的 Worker :
安装状态:已激活
运行状态:已停止
脚本:localhost / service-worker.js
...

范围:localhost / url
注册ID:112
活跃的 Worker :
安装状态:已激活
运行状态:已停止
脚本:localhost / service-worker.js
...

理想情况下,我想以某种方式将它保存到一个条目 .

2 回答

  • 14

    根据MDNServiceWorkerContainer.register 方法采用选项的第二个参数:

    当前可用的选项包括:scope:表示定义服务工作者注册范围的URL的USVString;服务工作者可以控制的URL范围 . 这通常是相对URL,未指定时默认为“/” .


    至于你更新的问题,W3C Service Workers WD说:

    当用户代理中已存在相同作用域URL时,服务工作者注册会导致现有服务工作者注册被替换 .

    因此 navigator.serviceWorker.register(url, {scope: '/'}).then(doSomething) 应该有效 .

    Problem is with the scope URL in your example:

    ./ 应为 /

  • 12

    在site-with-sub-directories场景中,您希望所有子页面都由同一顶级服务工作者控制,我建议使用绝对URL作为服务工作者脚本位置,然后依赖于省略 options.scope 时发生的默认行为 .

    请注意,其他响应中引用的MDN docs对于默认行为是不正确的 . 服务工作者specificationupdated in January 2015将默认范围更改为等同于 new URL('./', serviceWorkerScriptUrl).toString() . (MDN文档有since been updated,应该准确 . )

    为了说明为什么我建议在此用例中省略 options.scope ,请考虑以下备选方案,假设您需要单个共享服务工作者注册:

    • navigator.serviceWorker.register('/sw.js') 会给你一个范围为 / 的注册,这就是你想要的 .

    • navigator.serviceWorker.register('/sw.js', {scope: '/'}) 将为您提供范围为 / 的注册,这也是您想要的,但不会提供任何优于您使用默认行为的好处 .

    • navigator.serviceWorker.register('/subsite/sw.js', {scope: '/'}) 将无法注册,因为 / 的范围对于位于 /subsite/sw.js 的服务工作者脚本而言过于宽泛 .

    • navigator.serviceWorker.register('/subsite/sw.js') 将为您提供范围为 /subsite 的注册,这是您想要的 .

    • navigator.serviceWorker.register('/subsite/sw.js', {scope: '/subsite'}) 会起作用,但同样,它不会给你带来任何超过默认行为的好处 .

    我建议明确设置 options.scope 值的唯一时间是需要明确的时候将服务工作者的范围限制为比默认范围更窄 .

    请注意,如果您决定为 options.scope 提供值,并且该值是 './' 之类的相对URL,则URL将被解释为相对于调用 register() 的脚本/页面的位置 . {scope: './'}not 解释为相对于服务工作者脚本URL的位置 . 有一段时间我对这一点感到困惑,所以花一些时间来充分理解那里的含义 . 这就解释了为什么您在最初的问题中最终会进行多次注册 .

相关问题