向操作系统注册应用,使其成为文件处理程序。
现在,Web 应用能够读取和写入文件,因此下一步的合理做法是让开发者将这些 Web 应用声明为文件处理程序,以处理其应用可以创建和处理的文件。借助 File Handling API,您可以做到这一点。将文本编辑器应用注册为文件处理程序并安装后,您可以在 macOS 上右键点击 .txt 文件,然后选择“显示简介”,指示操作系统始终使用此应用作为默认应用来打开 .txt 文件。
File Handling API 的建议使用场景
以下是一些可能使用此 API 的网站示例:
- 办公应用,例如文本编辑器、电子表格应用和幻灯片制作工具。
- 图形编辑器和绘图工具。
- 视频游戏关卡编辑器工具。
如何使用 File Handling API
采用渐进增强的方式
File Handling API 本身无法进行 Polyfill。不过,您可以通过以下两种其他方式实现使用 Web 应用打开文件的功能:
- 借助 Web Share Target API,开发者可以将自己的应用指定为分享目标,以便从操作系统的分享表中打开文件。
- File System Access API 可以与文件拖放功能集成,以便开发者在已打开的应用中处理拖放的文件。
浏览器支持
功能检测
如需检查是否支持 File Handling API,请使用:
if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
// The File Handling API is supported.
}
File Handling API 的声明性部分
首先,Web 应用需要在其网络应用清单中以声明方式描述它们可以处理的文件类型。File Handling API 通过名为 "file_handlers" 的新属性扩展了 Web 应用清单,该属性接受文件处理程序数组。文件句柄是具有以下属性的对象:
- 一个
"action"属性,其值指向应用范围内的网址。 - 一个
"accept"属性,其中包含一个对象,该对象以 MIME 类型作为键,以文件扩展名列表作为值。 - 具有
ImageResource图标数组的"icons"属性。某些操作系统允许文件类型关联显示一个图标,该图标不仅是关联的应用图标,而且是与该文件类型在应用中的使用相关的特殊图标。 - 一个
"launch_type"属性,用于定义多个文件应在单个客户端中打开还是在多个客户端中打开。默认值为"single-client"。 如果用户打开多个文件,并且文件处理程序已使用"multiple-clients"注释作为其"launch_type",则会启动多个应用,并且每次启动时,LaunchParams.files数组(请参阅下文中的详细信息)都只会包含一个元素。
下面的示例仅显示了 Web 应用清单的相关摘录,应该能让您更清楚地了解这一点:
{
"file_handlers": [
{
"action": "/open-csv",
"accept": {
"text/csv": [".csv"]
},
"icons": [
{
"src": "csv-icon.png",
"sizes": "256x256",
"type": "image/png"
}
],
"launch_type": "single-client"
},
{
"action": "/open-svg",
"accept": {
"image/svg+xml": ".svg"
},
"icons": [
{
"src": "svg-icon.png",
"sizes": "256x256",
"type": "image/png"
}
],
"launch_type": "single-client"
},
{
"action": "/open-graf",
"accept": {
"application/vnd.grafr.graph": [".grafr", ".graf"],
"application/vnd.alternative-graph-app.graph": ".graph"
},
"icons": [
{
"src": "graf-icon.png",
"sizes": "256x256",
"type": "image/png"
}
],
"launch_type": "multiple-clients"
}
]
}
此示例适用于一个假设的应用,该应用在 /open-csv 处理以英文逗号分隔的值 (.csv) 文件,在 /open-svg 处理可缩放矢量图形 (.svg) 文件,并在 /open-graf 处理扩展名为 .grafr、.graf 或 .graph 的虚构 Grafr 文件格式。前两个将在单个客户端中打开,如果正在处理多个文件,则最后一个将在多个客户端中打开。
File Handling API 的命令式部分
现在,应用已声明理论上可以在哪些有效范围内的网址处理哪些文件,接下来需要在实践中强制性地对传入的文件执行某些操作。这时,launchQueue 就派上用场了。如需访问已启动的文件,网站需要为 window.launchQueue 对象指定使用方。启动会排队,直到由指定的消费者处理为止,每次启动都会调用一次该消费者。这样一来,无论何时指定了消费者,每次启动都会得到处理。
if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
launchQueue.setConsumer((launchParams) => {
// Nothing to do when the queue is empty.
if (!launchParams.files.length) {
return;
}
for (const fileHandle of launchParams.files) {
// Handle the file.
}
});
}
开发者工具支持
在撰写本文时,DevTools 尚不支持此功能,但我已提交功能请求,希望添加此支持。
演示
我已为卡通风格的绘图应用 Excalidraw 添加了文件处理支持。如需测试此功能,您需要先安装 Excalidraw。然后,当您使用该应用创建文件并将其存储在文件系统中的某个位置时,您可以通过双击打开该文件,也可以右键点击该文件,然后在上下文菜单中选择“Excalidraw”。您可以在源代码中查看实现。