declarative link capturing 由浏览器在导航前主动拦截并依 manifest.json 中的 capture_links 配置决定是否接管,字段名必须为 capture_links(下划线),仅支持 include("same-origin"/"cross-origin")和 exclude(路径前缀数组),且须置于 manifest 根层级;链接需满足无 target(或为"_self")、无 rel="external"/"noreferrer"/"noopener"、协议为 http/https、未按系统键、跨源时已声明权限等 5 个条件;handle_links 非标准字段,纯属误传;实际接管由 service worker 的 fetch 事件处理,且需真机验证行为一致性。

Declarative Link Capturing(声明式链接捕获)不是靠 JS 注册事件监听实现的,而是由浏览器在导航发起前主动拦截并交由 PWA 的 handle_links 配置决定是否接管——漏配、拼错字段或违反约束都会导致“看似配置了,实则完全不生效”。
manifest.json 中 capture_links 字段必须严格写对
字段名是 capture_links(下划线),不是 captureLinks、handle_links 或 link_handling。拼错就静默失效,连控制台警告都不会有。
-
include只接受字符串数组,合法值仅有"same-origin"(默认)和"cross-origin"(需额外声明"permissions": ["navigation"]) -
exclude是路径前缀数组,如["/blog/", "/admin/"],匹配逻辑是href.startsWith(excludeItem),优先级高于include - 整个
capture_links块必须放在 manifest 根层级,不能嵌套在web_app或其他自定义字段里
链接本身必须满足“可捕获”的 5 个硬性条件
即使 manifest 配置全对,只要链接带以下任一特征,浏览器就会跳过捕获、走默认跳转:
- 存在
target属性且值不为"_self"(例如target="_blank"、target="iframe1") - 存在
rel属性且含"external"、"noreferrer"、"noopener"等关键字(部分 UA 会据此 bypass) -
href协议非http或https(如mailto:、tel:、blob:、data:) - 用户点击时按住
Ctrl(Windows/Linux)或Cmd(macOS)键(系统级 bypass) - 链接目标跨 origin 但未在
include中声明"cross-origin",或未申请对应权限
handle_links 不是标准字段,别在 manifest 里写它
面试时如果被问到 “如何用 handle_links 实现链接捕获”,要立刻意识到这是常见误解:handle_links 并不存在于 Web App Manifest 规范中。规范只定义 capture_links。
- 某些旧文档或错误博客把
capture_links误写作handle_links,但实际运行时该字段会被完全忽略 - PWA 接管导航后,最终由 Service Worker 的
fetch事件或navigationPreload机制处理,不是靠 manifest 字段“触发回调” - 真正需要写代码的地方是 SW:监听
fetch事件 + 判断event.request.destination === 'document'+ 检查 URL 是否匹配业务规则
最容易被忽略的是:即使所有配置都对,Chrome for Android 上仍可能因 WebView 版本或 PWA 安装方式(如 “添加到主屏幕” vs “通过 Chrome 打开”)导致捕获行为不一致——务必在真机上验证,别只信桌面模拟器。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











