File System Access API 的永久性权限

现在,您可以获得对文件和文件夹的永久读写权限,而无需重复授予权限。这篇博文将介绍它的工作原理。在深入了解细节之前,请快速回顾一下现状和正在解决的问题。

当前方法存在的挑战

借助 File System Access API,开发者能够以读取和写入方式访问用户本地硬盘上的文件。使用此 API 的一个热门应用(以及许多其他应用)是 Visual Studio Code (VS Code),它是 Microsoft 的 IDE,可直接在浏览器中运行。当您打开 VS Code 后,系统会显示欢迎界面,您可以在其中创建新文件,也可以打开现有文件或文件夹。

Visual Studio Code 的欢迎界面。

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

Visual Studio Code 请求视图访问权限。

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

Visual Studio Code 请求编辑权限。

如果您允许此操作,地址栏中的文件图标会发生变化,并且系统会添加一个小向下箭头,表示应用具有读取和写入权限。如需更改权限,请依次点击该图标和移除访问权限,这样应用将无法再编辑文件。

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

访问权限将持续到您关闭源站的最后一个标签页为止。如果您随后关闭应用并再次打开,VS Code 类型可让您从上次停下的地方继续。点击打开最近打开的应用时,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 DevTools,在 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 两个标志切换为已启用

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

带有三向权限提示的 Visual Studio Code。

这个新的三向提示提供以下选项:

  • Allow this time:允许应用访问当前会话的文件。(这与现有行为一致。)
  • 每次访问时允许:除非访问权限被撤消,否则允许该应用拥有无限期的访问权限。应用被授予永久访问权限后,新打开的文件和文件夹也将始终可供访问。
  • 不允许:不允许该应用访问文件。(这与现有行为一致。)

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

带有文件编辑图标的 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 审核。