javascript 文件系统API声明它不能打开documents文件夹,因为它包含系统文件,而它不包含系统文件

j9per5c4  于 2022-10-30  发布在  Java
关注(0)|答案(2)|浏览(219)

我很难理解这是一个bug还是新的文件系统API的一个特性。当使用showDirectoryPicker并选择标准的Windows文档目录或下载目录时,会出现一个弹出窗口,说明它无法打开该文件夹,因为它包含系统文件,而实际上它并没有。有人找到了解决这个问题的方法吗?还是我遗漏了一些明显的东西?

下面是一个功能完整的示例:

<!DOCTYPE HTML>
<html>
<head>
  <title>File System API</title>
</head>
<button onclick="checkDirExists();">Initialize</button>
<body>

</body>
<script>

async function checkDirExists(){
    const homeDirHdl = await window.showDirectoryPicker({
        startIn: 'documents',
    });
    if (homeDirHdl){
        const draftsDirHdl = await homeDirHdl.getDirectoryHandle('drafts', {create: true});
    }
}
</script>
</html>
dluptydi

dluptydi1#

根据设计,文件系统访问API会禁止打开某些文件夹或限制对这些文件夹的访问。它们在规范中被列为所谓的已知目录。具体而言,它们是:

*desktop:使用者的桌面目录(如果存在的话)。例如,这可能是C:\Documents and Settings\username\Desktop/Users/username/Desktop/home/username/Desktop
*documents:通常用于存储用户创建的文档的目录。例如C:\Documents and Settings\username\My Documents/Users/username/Documents/home/username/Documents
*downloads:通常存储下载文件的目录。例如C:\Documents and Settings\username\Downloads/Users/username/Downloads/home/username/Downloads
*music:通常用于存储音频文件的目录。例如C:\Documents and Settings\username\My Documents\My Music/Users/username/Music/home/username/Music
*pictures:通常用于存储照片和其他静态图像的目录。例如C:\Documents and Settings\username\My Documents\My Pictures/Users/username/Pictures/home/username/Pictures
*videos:通常用于存储视频/电影的目录。例如C:\Documents and Settings\username\My Documents\My Videos/Users/username/Movies/home/username/Videos

通常,浏览器还会阻止对C:\Windowssystem 目录的访问。
阻止这些文件夹的原因是 (i),防止访问系统关键文件(Web应用程序应该无法擦除您的Windows文件夹)和 (ii) 防止档案被滥用作识别资料(* 例如 *,可以访问用户的下载文件夹的两个独立的应用程序可以创建标识文件并随后检查标识文件的存在)。有关更多详细信息和背景,请参见规范的相关部分。

8ulbf1ek

8ulbf1ek2#

正如https://stackoverflow.com/a/72027437/14188773所说,您不能使用FSA API函数来完成此操作,但可以使用drop/paste事件来完成此操作。例如,您可以复制/粘贴驱动器文件夹:

window.addEventListener('paste', handleInput)

  let driveHandles = {}
  async function handleInput ({ dataTransfer }) {
    const drives = [...dataTransfer.files].map(file => file.name.endsWith('_drive') && file.name[0])
    const handles = await Promise.all([...dataTransfer.items].map(item => item.getAsFileSystemHandle()))
    currentHandle = handles[0]
    for (let i = 0; i < drives.length; ++i) {
      const drive = drives[i]
      if (drive) {
        driveHandles[drive] = handles[i]
      }
    }
  }

这会创建一个驱动器句柄的Map,这些句柄是您通常无法使用FSA API访问的根文件夹,然后您可以通过IDB保存它们,并在会话中保持它们。这使您可以访问系统卷信息等内容

相关问题