如何为在客户站点上运行的 Service Worker 部署更新? [英] How to deploy updates to service workers running on customers' sites?

查看:70
本文介绍了如何为在客户站点上运行的 Service Worker 部署更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我提供不同网站使用的推送通知服务.此服务需要在我客户的站点上安装 Service Worker.我希望架构具有一些属性:

Suppose I provide a push notification service used by different websites. This service requires a service worker to be installed on my customers' sites. I want the architecture to have a few properties:

  • 完全静态资源.安装service worker文件和配置JS代码段等过程只需要做一次.
  • 能够随时更新 Service Worker.我希望能够随时更新 Service Worker 以修复错误、部署改进等.
  • Completely static resources. The process of installing the service worker files and configuring the JS snippet, etc. only needs to be done once.
  • The ability to update the service worker at any time. I want to be able to update the service worker at any time to fix bugs, deploy improvements, etc.

同时满足这两个约束是很困难的,因为浏览器只有在 Service Worker 脚本本身的内容发生变化时才会安装新版本的 Service Worker.(也就是说,不考虑通过 importScripts() 指定的依赖项.)

Satisfying both of these constraints is difficult because the browser only installs a new version of the service worker if the content of service worker script itself changes. (That is, without considering dependencies specified via importScripts().)

推荐答案

如果您无法更改 Service Worker 本身的内容,请考虑通过向 Service Worker URL 添加一个哈希值来创建一个新"Service Worker.这将导致浏览器在每次哈希更改时安装新"服务工作者.

If you can't change the contents of service worker itself, consider creating a "new" service worker by appending a hash to the service worker URL. This will cause the browser to install the "new" service worker every time the hash changes.

即替换代码如

navigator.serviceWorker.register("/sw.js");

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

安装新"Service Worker 后,浏览器将重新检查所有导入的脚本.(即使新"服务工作者与旧"服务工作者逐字节相同,这也适用,因为 URL 不同.)

When the "new" service worker is installed, the browser will re-check all imported scripts. (This applies even if the "new" service worker is byte-for-byte identical to the "old" one, because the URLs are different.)

如何生成哈希?

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

There's a few different ways to generate the hash. A completely random HASH will lead to the browser updating the service worker on every page load, which is unlikely to be what you want.

两种不同的方法:

  • (最好)您知道导入的脚本何时更改. 在这种情况下,仅在导入的脚本更改时更改 HASH.理想情况下,HASH 将是导入脚本本身内容的哈希值.
  • (好的)从时间导出哈希值. Math.floor(Date.now()/(3600 * 1000)) 将导致新"服务worker 每小时安装一次,这也将导致检查依赖项.(您可能还想应用一些抖动以避免所有客户端同时更新.)
  • (Best) You know when the imported script changes. In this case, only change HASH when the imported script changes. Ideally, HASH would be a hash of the contents of the imported script itself.
  • (Okay) Derive the hash from the time. Math.floor(Date.now() / (3600 * 1000)) will cause a "new" service worker to be installed every hour, which will also result in the dependencies being checked. (You'll probably also want to apply some jitter to avoid all clients updating at the same time.)

建议架构

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

If you provide a service-worker backed service to other websites (e.g. a push notification service), you can provide a completely static service worker and JS install snippet to your customers which allows you to control and trigger updates completely from your site.

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

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

JS snippet for customer to include on all HTML pages their site (static):

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

供客户在 https://example.com/sw.js 上安装的 Service Worker(静态):

Service worker for customer to install at https://example.com/sw.js (static):

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

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

您网站上的 Service Worker 注册代码 https://provider.com/register-sw.html?customer_id=8932e4288bc8(动态):

Service worker registration code on your site at https://provider.com/register-sw.html?customer_id=8932e4288bc8 (dynamic):

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

您网站上的真实"服务工作者 https://provider.com/imported-sw.js?customer_id=8932e4288bc8(动态):

"Real" service worker on your site at https://provider.com/imported-sw.js?customer_id=8932e4288bc8 (dynamic):

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

注意:字节对字节的要求是在过程中 以便此检查默认扩展到导入的脚本(不仅仅是注册的 URL 本身),但截至 2017 年 4 月,没有浏览器实现此行为.

NOTE: The byte-for-byte requirement is in the process of being changed so that this check extends to imported scripts by default (not just the registered URL itself), but as of April 2017 no browser implements this behavior.

这篇关于如何为在客户站点上运行的 Service Worker 部署更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆