如何将更新部署到在客户站点上运行的服务工作者?

时间:2017-04-18 11:58:57

标签: service-worker

假设我提供了不同网站使用的推送通知服务。此服务要求在我的客户站点上安装服务工作者。我希望架构有一些属性:

  • 完全静态资源。安装服务工作文件和配置JS代码段等的过程只需要完成一次。
  • 随时更新服务工作者的能力。我希望能够随时更新服务工作者以修复错误,部署改进等。

满足这两个限制很困难,因为如果服务工作者脚本本身的内容发生变化,浏览器只会安装新版本的服务工作者。 (也就是说,不考虑通过importScripts()指定的依赖关系。)

1 个答案:

答案 0 :(得分:3)

如果您无法更改服务工作者本身的内容,请考虑创建一个" new"服务工作者通过将哈希附加到服务工作者URL 。这将导致浏览器安装" new"每次哈希更改时服务工作者。

即,替换

之类的代码
navigator.serviceWorker.register("/sw.js");

navigator.serviceWorker.register(`/sw.js?hash=${HASH}`);

当"新"安装了service worker后,浏览器将重新检查所有导入的脚本。 (即使"新"服务工作人员与"旧"一个字节是逐字节相同的,这也适用,因为URL不同。)

如何生成哈希?

有几种不同的方法来生成哈希。完全随机的HASH将导致浏览器在每次加载页面时更新服务工作者,这不太可能是您想要的。

两种不同的方法:

  • (最佳)您知道导入的脚本何时更改。在这种情况下,仅在导入的脚本更改时更改HASH。理想情况下,HASH将是导入脚本本身内容的哈希值。
  • (好的)从时间中导出哈希值。 Math.floor(Date.now() / (3600 * 1000))会导致"新的"每小时安装一次服务工作者,这也会导致检查依赖项。 (您可能还想要应用一些抖动来避免所有客户端同时更新。)

建议的架构

如果您向其他网站提供服务工作者支持的服务(例如推送通知服务),您可以向您的客户提供完全静态的服务工作者和JS安装代码段,这样您就可以从您的站点完全控制和触发更新

customer.com的代码(全部静态):

JS代码段,供客户在其所有HTML网页上包含其网站(静态):

<script src="https://provider.com/register-sw.html?customer_id=8932e4288bc8">
</script>

客户的服务工作人员可以https://example.com/sw.js安装(静态):

importScripts("https://provider.com/imported-sw.js?customer_id=8932e4288bc8");

您网站的代码(可以是动态的):

您网站上的服务工作者注册码https://provider.com/register-sw.html?customer_id=8932e4288bc8(动态):

const HASH = hash_of_file("imported-sw.js");
navigator.serviceWorker.register(`/sw.js?hash=${HASH}`);

&#34;真&#34;您https://provider.com/imported-sw.js?customer_id=8932e4288bc8网站上的服务工作人员(动态):

// when service worker is updated, all clients receive
// update because service worker itself is "new"
self.addEventListener(...);

注意:字节为字节的要求是in the process of being changed,因此默认情况下此检查会扩展到导入的脚本(不仅仅是注册的URL本身),但截止到2017年4月没有浏览器实现了这种行为。