handle_links不是标准字段,纯属误传;规范只定义capture_links,且必须严格写为下划线格式、置于manifest根层级,拼错即静默失效。

HTML 中的 handle_links 不是标准 API,别白忙活了
HTML 本身没有 handle_links 这个属性或方法。你在 PWA 文档或社区里看到的 handle_links,几乎都指向 Workbox 的配置项(handleLinks),它只在 Service Worker 构建阶段起作用,和 HTML 标签、<a></a> 元素完全无关。直接在 HTML 里写 handle_links="true" 或类似属性,浏览器会静默忽略——它根本不认识。
Workbox 的 handleLinks 实际怎么用
这个选项控制的是:当用户点击页面内普通链接(比如 <a href="/about"></a>)时,Workbox 是否自动拦截并触发 navigationPreload 或自定义导航逻辑。但它只在调用 workbox.navigationPreload.enable() 且注册了导航路由时才生效。
-
handleLinks: true是 Workbox v6+ 的默认行为(无需显式写),但前提是已注册registerRoute(new NavigationRoute(...)) - 它不改变 HTML 渲染,也不影响链接跳转逻辑本身;只是让 Service Worker 有机会在导航请求发出前介入
- 如果你没启用 navigation preload,或者没配 NavigationRoute,设
handleLinks: true也毫无效果 - 常见误用:把它当成“让所有链接走 fetch 而不是跳转”,其实不是——它只是让 SW 能捕获那个导航请求,后续仍需你自己在
NavigationRoute回调里决定返回缓存、网络还是 fallback 页面
真正能捕获链接点击的,只有 JavaScript
想拦截点击、阻止默认跳转、手动处理路由(比如单页应用场景),唯一可靠方式是监听 click 事件并调用 event.preventDefault()。PWA 的离线能力不改变这点。
document.addEventListener('click', (event) => {
const link = event.target.closest('a[href]');
if (!link || link.href.startsWith('http') || link.href.startsWith('//')) return;
event.preventDefault();
// 手动 pushState + 渲染内容,或发 fetch 请求
history.pushState({}, '', link.href);
loadPage(link.href); // 自定义加载逻辑
});
- 必须用
event.target.closest('a[href]')判断,避免误拦按钮、图片等 - 要排除外链(含协议的 URL),否则会把用户困在当前域
- 记得同步更新
history.state,否则前进/后退失效 - Service Worker 无法帮你做这件事——它在请求层,而点击拦截在 DOM 层
为什么你搜到的示例总“不生效”
很多教程把 Workbox 配置、SW 注册、前端路由三者混在一起讲,却没强调执行顺序和依赖条件。最常踩的坑:
- 写了
handleLinks: true,但没调用workbox.navigationPreload.enable() - 注册了
NavigationRoute,但回调函数里没返回 Response(比如忘了return caches.match(...)或return fetch(...)),导致白屏 - HTML 中用了
target="_blank"或download属性的链接,Workbox 默认不拦截这类导航 - 本地开发用
file://协议打开 HTML,Service Worker 根本不会注册(必须通过http://或https://)
真正关键的不是加某个属性,而是确认 Service Worker 已激活、navigation route 已注册、且你的页面请求路径匹配该 route 的正则或条件。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











