service worker 处理带鉴权请求需拦截请求、动态注入令牌并同步等待最新令牌;须用 indexeddb 或内存管理 token,通过 postmessage 获取初始值,在 fetch 事件中克隆请求并添加 authorization 头,配合 promise 引用机制支持刷新与排队,且必须启用 https、正确设置 scope 和 credentials。

Service Worker 处理带鉴权的网络请求,核心在于拦截请求 + 动态注入令牌 + 同步等待最新令牌。它不能直接读取页面 localStorage 或 sessionStorage 中的 token,也不能访问 DOM,所以必须在 Service Worker 内部独立管理认证状态,并确保所有受保护的请求都使用当前有效的凭证。
令牌需在 Service Worker 内部统一管理
页面 JS 设置的 Authorization header 不会自动透传给 Service Worker 的 fetch 请求。你必须显式地在 fetch 事件中添加认证头:
- 不能依赖页面 JS 的全局变量或闭包——Service Worker 是独立线程,无共享作用域
- 推荐将令牌存在 IndexedDB(持久)或内存变量(轻量、重启丢失)中,避免用 cache API 存敏感信息
- 首次加载时,可通过 postMessage 从页面传入初始 token,或由 Service Worker 主动向认证接口发起请求获取
请求拦截时动态附加 Authorization 头
在 fetch 事件中识别需鉴权的请求(如匹配 /api/、/v1/ 等路径),再注入 token:
- 用 request.url 判断是否属于受保护接口
- 克隆原始 request,用 new Request(url, { ...init, headers: newHeaders }) 构造新请求
- headers 需基于原 headers 克隆后追加:'Authorization': 'Bearer ' + token
- 注意:不能直接修改 request.headers(只读),必须新建 Request 实例
支持令牌刷新与请求排队等待
当 token 过期需刷新时,不能让后续请求失败或使用旧 token。正确做法是用 Promise 引用替换机制:
- 定义一个 let currentTokenPromise = getFreshToken() 变量,始终指向“获取当前有效 token”的 Promise
- 刷新时(如定时器触发),调用 getFreshToken() 获取新 Promise,并重新赋值给 currentTokenPromise
- 每个 fetch 处理中 await currentTokenPromise,自然等待最新 token 就绪后再发请求
- 错误时应 reject 并在 catch 中返回 401 响应,避免静默失败
避免常见陷阱
实际部署中容易忽略的关键细节:
- HTTPS 强制要求:Service Worker 只能在 HTTPS 或 localhost 下注册,否则无法生效
- scope 权限限制:注册时指定的 scope 决定了能拦截哪些请求,/sw.js 注册在根目录才可拦截全部
- 跨域请求默认不带 credentials:fetch 选项中需显式设置 credentials: 'include' 才发送 cookie 或 auth header
- 缓存策略冲突:带 Authorization 的请求默认不被 cache API 缓存(Response 不含 Vary: Authorization 时可能出错),建议对鉴权接口禁用缓存或手动处理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











