处理文件
发布于
一句话概括: 在 Web App Manifest 中声明 file_handlers,会将已安装的 PWA 注册为
操作系统对特定文件类型的处理程序,这样双击或使用“打开方式”打开匹配的文件时会直接以该
文件启动你的应用,而无需你自己搭建一套单独的导入流程。
1. 在 manifest 中声明 file_handlers
Section titled “1. 在 manifest 中声明 file_handlers”根据 Chrome for Developers 的说明,每个文件处理程序都需要一个位于应用作用域内的
action URL、一个将 MIME 类型映射到文件扩展名的 accept 对象,以及一个可选的
icons 数组,使操作系统能够展示特定文件类型的图标而不只是应用图标:
{ "file_handlers": [ { "action": "/open-csv", "accept": { "text/csv": [".csv"] }, "icons": [ { "src": "/icons/csv-icon.png", "sizes": "256x256", "type": "image/png" } ], "launch_type": "single-client" } ]}launch_type 决定同时打开多个匹配文件时是复用同一个应用窗口("single-client",
默认值),还是使用 "multiple-clients" 为每个文件各启动一次应用,每次启动的
LaunchParams.files 数组仅包含该文件。
2. 用 launchQueue 接收被启动的文件
Section titled “2. 用 launchQueue 接收被启动的文件”根据 MDN 的说明,一旦操作系统以匹配的文件启动应用,应用会通过
window.launchQueue.setConsumer() 接收该文件:
window.launchQueue.setConsumer(async (launchParams) => { if (!launchParams.files.length) { return; } const [fileHandle] = launchParams.files; const file = await fileHandle.getFile(); const text = await file.text(); renderCsv(text);});- 图例
- 支持
- 部分支持
- 需开启标志
- 不支持
- 未知
| 浏览器 / 平台 | 支持 | 版本 | 置信度 | 来源 | 备注 |
|---|---|---|---|---|---|
| Chrome (Desktop) | 支持 | 102 | 高 | 来源 | — |
| Chrome (Android) | 不支持 | — | 高 | 来源 | 1 |
| Edge (Desktop) | 支持 | 102 | 高 | 来源 | 2 |
| Firefox (Desktop) | 不支持 | — | 高 | 来源 | 3 |
| Firefox (Android) | 不支持 | — | 高 | 来源 | 45 |
| Safari (macOS) | 不支持 | — | 高 | 来源 | 6 |
| Safari (iOS) | 不支持 | — | 高 | 来源 | 78 |
| Samsung Internet | 不支持 | — | 高 | 来源 | 910 |
| WebView (Android) | 不支持 | — | 高 | 来源 | 1112 |
- browser-compat-data 未记录 Chrome Android 的支持。
- 由 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 未记录 Samsung Internet 的支持。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
- browser-compat-data 未记录 WebView Android 的支持。
- 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
根据 Chrome for Developers 的说明,文件处理在 Chromium 的实现中“仅限于桌面操作系统”—— 不要指望它能在 Android 上把文件与应用关联起来。
3. 检测支持情况并提供回退
Section titled “3. 检测支持情况并提供回退”根据 Chrome for Developers 的说明,请同时使用 "launchQueue" in window 与
"files" in LaunchParams.prototype 两项特性检测,因为仅有 launchQueue 并不能确认
consumer 所依赖的 files 参数形态。当任意一项检测失败时,为用户提供一个不依赖操作
系统注册的应用内打开方式:
function supportsFileHandling() { return 'launchQueue' in window && 'files' in LaunchParams.prototype;}
if (supportsFileHandling()) { window.launchQueue.setConsumer(async (launchParams) => { if (!launchParams.files.length) return; const file = await launchParams.files[0].getFile(); renderCsv(await file.text()); });} else { // 此处不支持 File Handling——改用界面中手动的 // <input type="file" accept=".csv"> 选择器。 document.getElementById('open-file-input').hidden = false;}- 根据 Chrome for Developers 的说明,
file_handlers注册在 Chromium 中仅限桌面端—— 务必始终提供一个应用内文件选择器,作为 Android 端或回退路径。 - 请同时使用
"launchQueue" in window与"files" in LaunchParams.prototype两项检测(根据 Chrome for Developers 的说明)——仅检测launchQueue无法确认setConsumer()回调所依赖的files参数形态。 - 根据 Chrome for Developers 的说明,
launchQueue会将启动事件排队,直到有 consumer 被注册,且无论何时注册,每次启动都会被处理且仅处理一次——但 consumer 函数本身仍 必须先运行才能读到被启动的文件,因此不要把它的注册挂在其他异步启动逻辑之后。 - Firefox 与 Safari 均未实现
file_handlers——不要把操作系统级别的文件关联当作进入 该功能的唯一方式。
- manifest: file_handlers 支持情况 —— 完整
的兼容性数据与
file_handlersmanifest 参考。 - 接收分享的内容(share target) —— 一篇相关指南,介绍如何 通过操作系统分享面板接收其他应用分享的文件与数据。