假设我提供了不同网站使用的推送通知服务。此服务需要在我客户的站点上安装 Service Worker。我希望架构具有一些属性:
满足这两个约束是很困难的,因为浏览器只有在 Service Worker 脚本本身的内容发生变化时才会安装新版本的 Service Worker。(也就是说,不考虑通过importScripts().指定的依赖项。)
如果您无法更改 Service Worker 本身的内容,请考虑通过向Service Worker URL附加哈希来创建“新”Service Worker 。这将导致浏览器在每次哈希更改时安装“新”服务工作者。
也就是说,替换代码如下
navigator.serviceWorker.register("/sw.js");
Run Code Online (Sandbox Code Playgroud)
和
navigator.serviceWorker.register(`/sw.js?hash=${HASH}`);
Run Code Online (Sandbox Code Playgroud)
安装“新”服务工作者后,浏览器将重新检查所有导入的脚本。(即使“新”服务工作者与“旧”服务工作者逐字节相同,这也适用,因为 URL 不同。)
如何生成哈希?
有几种不同的方法来生成哈希。完全随机HASH将导致浏览器在每次页面加载时更新服务工作者,这不太可能是您想要的。
两种不同的方法:
HASH在导入的脚本更改时才更改。理想情况下,HASH将是导入脚本本身的内容的散列。Math.floor(Date.now() / (3600 * 1000))将导致每小时安装一个“新”服务工作者,这也将导致检查依赖项。(您可能还想应用一些抖动以避免所有客户端同时更新。)建议的架构
如果您向其他网站提供 service-worker 支持的服务(例如推送通知服务),您可以向您的客户提供完全静态的 service worker 和 JS 安装片段,这允许您完全从您的站点控制和触发更新。
customer.com 的代码(都是静态的):
供客户在其网站的所有 HTML 页面上包含的 JS 片段(静态):
<script src="https://provider.com/register-sw.html?customer_id=8932e4288bc8">
</script>
Run Code Online (Sandbox Code Playgroud)
Service Worker 供客户在https://example.com/sw.js上安装(静态):
importScripts("https://provider.com/imported-sw.js?customer_id=8932e4288bc8");
Run Code Online (Sandbox Code Playgroud)
您网站的代码(可以是动态的):
您网站上的 Service Worker 注册码https://provider.com/register-sw.html?customer_id=8932e4288bc8(动态):
const HASH = hash_of_file("imported-sw.js");
navigator.serviceWorker.register(`/sw.js?hash=${HASH}`);
Run Code Online (Sandbox Code Playgroud)
您网站上的“真实”服务工作者,网址为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(...);
Run Code Online (Sandbox Code Playgroud)
注意:逐字节要求正在更改,以便此检查默认扩展到导入的脚本(不仅仅是注册的 URL 本身),但截至 2017 年 4 月,没有浏览器实现此行为。
| 归档时间: |
|
| 查看次数: |
1231 次 |
| 最近记录: |