Manifest · 清单成员
launch_handler 清单成员
发布于
launch_handler 告诉浏览器:已安装的 Web 应用再次被启动时(来自系统启动器、快捷方式、文件关联、
协议链接或分享),该怎样处理它已经打开的窗口。它唯一的属性 client_mode 在三种做法之间选择:
聚焦已打开的窗口、让该窗口导航到启动 URL,或新开一个窗口。
Chrome 110、Edge 110、Samsung Internet 21.0 与 Android WebView 110 实现了该成员(BCD
html.manifest.launch_handler)。Firefox 157 与 Safari 27 解析后丢弃,所以在那里每次启动都会
新开窗口或标签页。启动 URL 通过 window.launchQueue 送达页面,focus-existing 正是靠它才有用。
- 类型:对象,只有一个属性
client_mode,取字符串或字符串数组。允许的值:auto、navigate-new、navigate-existing、focus-existing。 - 默认值:
auto。成员缺省、client_mode不是字符串或数组、数组里没有任何可识别的值, 这三种情况都解析为auto。 - 示例值:
{ "client_mode": ["focus-existing", "auto"] }。
已有窗口打开时,各模式的行为:
auto把选择权交给浏览器。Chromium 在 Android 上取navigate-existing(单实例是常态), 在桌面端取navigate-new。navigate-new在启动 URL 处新开一个应用窗口。navigate-existing把最近使用的窗口提到前台,并让它导航到启动 URL。focus-existing把该窗口提到前台但不导航。页面通过launchQueue收到启动 URL,自行决定 怎么处理。
没有窗口打开时,focus-existing 与 navigate-existing 的表现等同于 navigate-new。对于数组,
浏览器取第一个它认得的值,因此清单可以优先 focus-existing,同时为将来新增模式的引擎写上 auto。
Chromium 解析器对形状很严格:非对象的值产生 launch_handler value ignored, object expected.,
client_mode 中未知的字符串产生 client_mode value '<value>' ignored, unknown value.
(manifest_parser.cc 的 ParseLaunchHandler)。被跳过的只是无效条目,不是整个成员。
清单一侧只有一行;有意思的代码在 launchQueue 消费者里,是它让 focus-existing 真正做事。
保持单一编辑器窗口并把启动导入其中
Section titled “保持单一编辑器窗口并把启动导入其中”一个文档编辑器只想要一个窗口,每次启动切换到被请求的文档,而不是堆叠窗口。清单请求
focus-existing;页面消费启动 URL 并更新自身状态。
{ "name": "Draft", "start_url": "/", "display": "standalone", "launch_handler": { "client_mode": ["focus-existing", "auto"] }, "file_handlers": [ { "action": "/open", "accept": { "text/markdown": [".md"] } } ]}if ('launchQueue' in window) { window.launchQueue.setConsumer(async (launchParams) => { const url = new URL(launchParams.targetURL); if (launchParams.files.length > 0) { const file = await launchParams.files[0].getFile(); await openDocument(file); return; } const doc = url.searchParams.get('doc'); if (doc) await openDocumentById(doc); });} else { // 没有 launchQueue:浏览器做的是普通导航,直接读 URL 即可。 const doc = new URL(location.href).searchParams.get('doc'); if (doc) await openDocumentById(doc);}消费者会为创建该窗口的那次启动运行一次,之后每一次被导入该窗口的启动再运行一次。启动来自文件
关联时,launchParams.files 是 FileSystemFileHandle 数组,否则为空。
检测该 API 并回退到普通导航
Section titled “检测该 API 并回退到普通导航”launchQueue 是整套机制的检测点。没有它的浏览器会把每次启动都变成到 targetURL 的普通导航,
所以回退就是读 location。下面的辅助函数让应用其余部分无论哪种情况都只面对一个回调。
export function onLaunch(handler) { if ('launchQueue' in window) { window.launchQueue.setConsumer((params) => handler(new URL(params.targetURL))); } else { handler(new URL(location.href)); }}
onLaunch((url) => { if (url.pathname === '/share') showShareSheet(url.searchParams);});在模块的第一个 await 之前注册消费者:Chromium 会把启动参数排队到有消费者为止,晚注册的
消费者仍会被触发,所以不会丢,只会延迟。
桌面端偏好新窗口、移动端偏好现有窗口
Section titled “桌面端偏好新窗口、移动端偏好现有窗口”一个新闻阅读器希望桌面端每次启动都在自己的窗口里,而在手机上只保留一个窗口。auto 在
Chromium 里已经编码了这种区分,清单把它显式写出来,把选择交给浏览器。
{ "launch_handler": { "client_mode": "auto" }}写出 auto 与省略该成员等价;这个值存在的意义是让日后修改清单时有一个明显的位置可改。
- file_handlers 清单成员
- protocol_handlers 清单成员
- share_target 清单成员
- start_url 清单成员
- Web App Launch Handler API: launch_handler member(wicg.github.io)
- Control how your app is launched(developer.chrome.com)
- LaunchQueue(developer.mozilla.org)
规范
| 规范 | 状态 |
|---|---|
| Web 应用清单:launch_handler | WICG 草案 |
- 图例
- 支持
- 部分支持
- 需开启标志
- 不支持
- 未知
| 浏览器 / 平台 | 支持 | 版本 | 置信度 | 来源 | 备注 |
|---|---|---|---|---|---|
| Chrome (Desktop) | 支持 | 110 | 高 | 来源 | — |
| Chrome (Android) | 支持 | 110 | 高 | 来源 | 1 |
| Edge (Desktop) | 支持 | 110 | 高 | 来源 | 2 |
| Firefox (Desktop) | 不支持 | — | 高 | 来源 | 3 |
| Firefox (Android) | 不支持 | — | 高 | 来源 | 45 |
| Safari (macOS) | 不支持 | — | 高 | 来源 | 6 |
| Safari (iOS) | 不支持 | — | 高 | 来源 | 78 |
| Samsung Internet | 支持 | 21.0 | 高 | 来源 | 9 |
| WebView (Android) | 支持 | 110 | 高 | 来源 | 10 |
- 由 browser-compat-data 镜像自 Chrome 的数据推导。
- 由 browser-compat-data 镜像自 Chrome 的数据推导。
- browser-compat-data 未记录 Firefox 的支持。
- browser-compat-data 未记录 Firefox for Android 的支持。
- 由 browser-compat-data 镜像自 Firefox 的数据推导。
- browser-compat-data 未记录 Safari 的支持。
- browser-compat-data 未记录 iOS 版 Safari 的支持。
- 由 browser-compat-data 镜像自 Safari 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。