Service Worker 可拦截请求并动态生成 HTML 响应,支持按需拼装页面区块、个性化变量注入及灵活缓存策略。

Service Worker 可以拦截网络请求并动态生成响应,无需预先构建完整 HTML 文件,非常适合实现按需拼装页面内容(比如个性化首页、A/B 测试页、多语言模板注入等)。
拦截请求并构造 Response 对象
在 fetch 事件中,判断目标 URL(如匹配 /app/ 开头的路径),然后调用 event.respondWith() 返回自定义 Response。响应体可以是字符串、ReadableStream 或 FormData 等。
- 使用
new Response(body, { headers, status })创建响应,body可为 HTML 字符串或通过模板函数生成 - 注意设置
Content-Type: text/html; charset=utf-8,否则浏览器可能解析异常 - 若需异步获取数据(如从 IndexedDB 或 Cache API 读取模块片段),可用
async/await配合event.respondWith()
按需拼装:分块加载 + 动态注入
将页面拆分为逻辑区块(header、nav、main、footer),每个区块可独立缓存或按条件渲染。Service Worker 在拦截时组合这些片段:
- 从
caches.open('blocks')中并行读取多个缓存键(如'header_zh'、'featured_promo_v2') - 根据
event.request.destination === 'document'和请求头(如Accept-Language)决定使用哪组区块 - 用字符串模板或轻量函数(如
html`${header}${main}${footer}`)拼接,避免 DOM 操作开销
支持个性化与上下文变量
动态响应可读取客户端传入的上下文,例如 URL 查询参数、Cookie(需配合 request.headers.get('cookie'))、或本地存储标识(需提前通过 postMessage 同步到 SW):
- 解析
new URL(event.request.url).searchParams获取theme=dark、user_id=123等参数 - 结合预存的用户偏好(从 IndexedDB 加载)决定是否展示某模块,或替换文案占位符(如
${userName}→张三) - 敏感信息(如 token)不建议在 SW 中处理,应由后端接口返回结构化数据,SW 仅做组装
缓存策略与更新控制
动态生成的内容默认不缓存,但可按需写入 Cache API,提升后续访问性能:
- 对「稳定」的组合(如
/app/?lang=zh&theme=light)生成唯一 cacheKey,存入缓存并设置 TTL(通过自定义 header 或时间戳标记) - 监听
message事件,接收主页面发来的「清除某类动态页缓存」指令(如用户切换语言后触发) - 避免缓存含实时数据的页面(如仪表盘),改用
stale-while-revalidate模式:先返回缓存 HTML,再后台更新

















