service worker 不直接执行路由重定向,而是通过拦截 document 请求并返回 index.html 实现伪重定向,使前端路由接管渲染;需按 destination 分流、避免递归循环,并在 sw 激活后初始化路由以保障离线体验。

Service Worker 本身不直接处理单页应用(SPA)的路由重定向逻辑,但它能为 SPA 的路由跳转提供底层支撑——尤其在离线、缓存命中、URL 拦截等场景下,间接影响重定向行为。关键在于:它不执行 router.push 或 history.replaceState 这类前端路由操作,而是通过拦截网络请求、重写响应、控制资源加载路径,来“配合”或“触发”前端路由系统的重定向策略。
拦截请求并重定向到 fallback 页面
当用户访问一个未缓存的动态路由(如 /user/123),而此时网络不可用,Service Worker 可主动将该请求重定向到已缓存的兜底页面(如 /offline.html 或 /index.html),让前端路由接管:
- 监听
fetch事件,在event.request.destination === 'document'时判断是否为 HTML 页面请求 - 若请求路径匹配 SPA 路由规则(如
/post/456、/dashboard),且当前离线或资源未命中缓存,则返回cache.match('/index.html') - 这样浏览器仍显示原 URL,但加载的是
index.html,Vue Router / React Router 等会自动解析当前路径并渲染对应组件——视觉上就像“重定向到了首页再跳转过去”,实则无刷新
配合前端路由实现“伪重定向”缓存策略
某些场景下,你希望用户访问 /old-path 时,实际展示 /new-path 的内容,但 URL 不变(SEO 友好)或需保持历史记录。Service Worker 可以:
- 在
fetch中识别/old-path请求,不真正发起网络请求,而是直接return cache.match('/new-path.html')或respondWith(new Response(...)) - 注意:这只是内容替换,不是导航跳转;真正的“重定向”仍由前端路由完成(例如监听 URL 后调用
router.replace('/new-path')) - 这种组合可避免服务端 301 重定向带来的额外 RTT,也绕过服务端配置依赖
避免重定向循环的关键守则
Service Worker 若错误地对 index.html 本身做递归重定向,极易引发无限 fetch 循环(比如每次返回 index.html,又触发对它的再次请求)。必须严格限制:
- 只对
destination === 'document'的请求做 fallback,排除 CSS/JS/图片等资源请求 - 检查
event.request.url是否已为 fallback 路径(如/index.html),避免二次匹配 - 不修改
event.request.url后直接fetch()原路径(易造成死循环),应明确区分“资源请求”和“页面导航请求”
与前端路由协同的初始化时机
SPA 加载时,若 Service Worker 尚未激活,而用户已触发路由跳转(如从 /login 到 /dashboard),可能因资源未缓存导致白屏。因此:
- 注册 SW 后,可监听
controllerchange或statechange,待其激活后再启用前端路由的完整能力 - 部分框架(如 Angular、UI-Router)支持
$urlRouterProvider.deferIntercept(),即延迟路由解析,直到 SW 准备就绪 - 也可在
navigator.serviceWorker.ready后再挂载 Vue/React 应用,确保首次导航就有缓存保障
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











