File System Access API 的永久性权限

现在,您可以获得对文件和文件夹的永久读写权限,而无需反复授予权限。本文介绍了其运作方式。在深入了解详情之前,我们先来快速回顾一下现状和要解决的问题。

当前方法存在的问题

借助 File System Access API,开发者可以以读取和(可选)写入方式访问用户本地硬盘上的文件。Visual Studio Code (VS Code) 是利用此 API 的众多应用之一,它是 Microsoft 的 IDE,可直接在浏览器中运行。打开 VS Code 后,您会看到 Welcome 屏幕,您可以在其中创建新文件,或打开现有文件或文件夹。

Visual Studio Code 的欢迎界面。

如果您点击打开文件夹并选择硬盘上的某个文件夹,浏览器会询问您是否要让 VS Code 拥有对此文件夹的查看权限。

Visual Studio Code 请求查看权限。

授予访问权限后,您就可以浏览文件夹层次结构,并在 VS Code 的编辑器中打开文件。如果您修改了任何文件,浏览器会询问您是否要授予对该文件夹的编辑权限。

Visual Studio Code 请求编辑权限。

如果您允许,地址栏中的文件图标会发生变化,并会添加一个向下小箭头,表示该应用具有读取和写入权限。如需更改权限,请点击该图标,然后点击撤消权限,以便该应用无法再修改文件。

显示地址栏图标提示的 Visual Studio Code。

访问权限会持续到您关闭来源的最后一个标签页。然后,如果您关闭该应用并重新打开,VS Code 可以让您从上次停下的地方继续。点击 Open Recent(打开最近用过的文件)时,VS Code 会提供之前打开的文件夹以供重新打开。

Visual Studio Code 显示最近打开的文件。

不过,即使您之前已向该文件夹授予写入权限,现在也需要再次授予访问权限。这很快就会让人疲倦。在深入探讨解决方案(即 File System Access API 的永久性权限)之前,我们先来看看 VS Code 是如何记住近期打开的文件夹的。

Visual Studio Code 在重新加载后请求修改权限。

在 File System Access API 中,通过 FileSystemHandle 对象管理对文件和文件夹的访问权限:FileSystemFileHandle 对象用于文件,FileSystemDirectoryHandle 对象用于文件夹(目录)。这两者都可以存储在 IndexedDB 中,而 VS Code 正是这么做的。如需查看,请打开 Chrome 开发者工具,在 Application(应用)标签页中前往 IndexedDB 部分,然后在 vscode-web-db 数据库中选择相关表 vscode-filehandles-store

Chrome 开发者工具调试 Visual Studio Code,其中显示了包含存储的 FileSystemHandle 的 IndexedDB 部分。

新方式:具体变化及时间

Chrome 将推出新行为,让用户可以选择授予对其文件和文件夹的永久访问权限,从而避免不断重复提示用户。从 Chrome 122 开始,您就可以观察到新行为。如需更早进行测试,请从 Chrome 120 开始,将两个标志 chrome://flags/#file-system-access-persistent-permissionchrome://flags/#one-time-permission 切换为 Enabled

首先,新行为包含一个新的三选一权限提示,可让用户选择在每次访问时授予应用对所选文件和文件夹的访问权限。

显示三种方式的权限提示的 Visual Studio Code。

这个新的三选一提示包含以下选项:

  • 仅此时刻:允许应用访问当前会话的文件。(这与现有行为一致。)
  • 每次访问时都允许:除非撤消访问权限,否则允许应用无限期访问。向应用授予永久访问权限后,新打开的文件和文件夹也将可永久访问。
  • 不允许:不允许应用访问文件。(这与现有行为相对应。)

其次,新行为会在网站设置中新增一个部分,用户可以通过文件修改切换开关旁边的启动图标访问该部分。

显示文件编辑图标的 Visual Studio Code 网站设置。

点击此启动图标可打开相关应用的隐私和安全设置,用户可以在其中看到该应用有权访问的所有文件和文件夹的项列表。您可以点击回收站图标,按项目撤消访问权限。移除按项访问权限意味着应用仍然可以获得对文件的一般访问权限。通常,如需撤消访问权限,用户可以点击地址栏中的图标,如前所述。

vscode.dev 网站的 Chrome 隐私和安全设置。

如何触发新行为

File System Access API 没有面向开发者的任何更改。如需使用永久性权限触发新行为,有三种方法,需要满足不同的前提条件:

  1. 用户必须在上次访问某个源时授予对某个文件或文件夹(或多个文件或文件夹)的权限,并且应用必须已在 IndexedDB 中存储相应的 FileSystemHandle 对象。在下次访问来源时,应用必须从 IndexedDB 检索任何一个存储的 FileSystemHandle 对象,然后调用其 FileSystemHandle.requestPermission() 方法。如果满足这些前提条件,系统会显示新的三方提示。
  2. 来源必须对之前已被授予访问权限但由于标签页在后台运行了一段时间而自动撤消访问权限的 FileSystemHandle 调用了 FileSystemHandle.requestPermission() 方法。(自动撤消权限的运作方式与Chrome 中的一次性权限一文中所述的逻辑相同。)如果满足这些前提条件,系统会显示新的三方提示。
  3. 用户必须已安装该应用。已安装的应用会在用户授予访问权限后自动保留权限。在这种情况下,系统不会显示三选一提示,而是默认让应用采用新行为。

在第一种和第二种情况下,提示会列出应用之前有权访问的所有 FileSystemHandle 对象,而不仅仅是正在调用 requestPermission() 方法的对象。与一次性权限的运作方式一致,如果用户拒绝或关闭提示超过三次,系统将不再触发该提示,而是显示常规权限提示。

试用新行为

如果您使用的是受支持的 Chrome 版本或已设置所需的标志,则可以在 Web 上的 VS Code 中测试新行为。打开一个文件夹并授予访问权限,然后关闭该标签页并重新打开,然后点击打开近期打开的标签页(请注意,立即重新加载无法触发提示,需要关闭所有标签页)。选择上一个文件夹,系统随即会显示新提示。如需更精简的测试用例,请查看永久性文件系统访问演示查看其源代码

总结

File System Access API 的永久性权限是该 API 的最热门功能之一,实现 bug 也非常受欢迎,许多开发者都将其列为关注项。通过将此功能交到开发者手中,尤其是交到用户手中,我们现在填补了与平台专用应用相比的一项重要功能差距。

致谢

此博文由 Christine HollingsworthAustin SullivanRachel Andrew 审核。