Service Worker 不能单独统一管理灰度发布,需构建、CDN/网关、运行时三方协同:构建层生成带版本标识的资源与SW脚本;CDN/网关层在HTML响应阶段按灰度策略分流;运行时SW在fetch事件中基于版本隔离缓存。

Service Worker 本身不能“统一管理”灰度发布,它只是执行层。真正实现前端静态资源的版本灰度发布,必须靠构建、CDN/网关、运行时三者协同,SW 负责按运行时上下文做精准缓存读写。
构建层:生成带版本标识的资源与 SW 脚本
每次构建产出唯一语义化版本(如 v2.5.0 或 20260520-abc123),并贯穿所有环节:
- 静态资源文件名嵌入内容哈希(app.a1b2c3.js),确保变更即新 URL,规避 CDN 和浏览器复用旧缓存
- Service Worker 脚本命名为 sw-v2.5.0.js 或带查询参数(/sw.js?v=v2.5.0),避免浏览器强缓存旧版
- 生成资源清单 manifest-v2.5.0.json,精确列出所有带版本路径的静态文件,供 install 阶段预缓存
- HTML 模板由服务端或构建时动态注入对应注册语句:navigator.serviceWorker.register('/sw-v2.5.0.js')
CDN/网关层:在入口处完成灰度分流
灰度决策不能放在前端 JS 或 SW 里做,必须前置到 HTML 响应阶段——这是隔离性和可控性的关键。
- 根据请求头(X-Gray-Version: v2.5.0)、Cookie(gray-version=v2.5.0)或用户 ID 哈希,边缘节点返回对应版本的 HTML 片段
- 返回的 HTML 中已固化:SW 注册地址、静态资源 base URL(如 /static/v2.5.0/)、全局版本变量(window.__SW_VERSION = 'v2.5.0')
- 不同版本资源路径物理隔离(/static/v2.4.0/ 与 /static/v2.5.0/ 不共享 CDN 缓存),天然避免错配
运行时:SW 中基于版本构造缓存键
fetch 事件是唯一可读取灰度上下文的地方,必须在这里做版本感知和缓存隔离。
立即学习“前端免费学习笔记(深入)”;
- 从 document.cookie 或 event.request.headers.get('X-Gray-Version') 读取当前版本(install/activate 阶段不可读)
- 缓存 key 必须含版本信息,例如:https://cdn.example.com/app.js?v=v2.5.0,而非裸 URL
- 推荐统一使用 caches.open('static'),但 key 拼接版本;或按版本开独立缓存(caches.open('static-v2.5.0'))
- 对关键资源(首屏 JS/CSS/HTML)可加失败计数逻辑:连续失败后自动尝试上一稳定版本的 cache key,实现轻量降级
回滚机制:切换入口,而非重写 SW
所谓“多级回滚”,本质是快速切回历史版本的完整链路,不是让一个 SW 脚本倒退状态。
- 所有历史版本的 HTML、SW 脚本、静态资源均保留在 CDN,路径按版本隔离
- 触发回滚时,只需让网关将灰度标识指向历史版本(如从 v2.5.0 切回 v2.4.1),用户下次访问即加载整套旧快照
- 旧版 SW 的 activate 事件中清理过期缓存(caches.delete('static-v2.5.0')),但保留非镜像类缓存(如图片、API 数据)


















