假设我提供了不同网站使用的推送通知服务。此服务要求在我的客户站点上安装服务工作者。我希望架构有一些属性:
满足这两个限制很困难,因为如果服务工作者脚本本身的内容发生变化,浏览器只会安装新版本的服务工作者。 (也就是说,不考虑通过importScripts()
指定的依赖关系。)
答案 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月没有浏览器实现了这种行为。