navigator.storage.getdirectory()无法获取opfs根目录,必须通过showdirectorypicker()由用户选择文件夹并请求读写权限后持久化才能获得可稳定使用的opfs根句柄。

navigator.storage.getDirectory 无法直接访问 Origin Private File System 根目录
不能。navigator.storage.getDirectory() 本身不返回 OPFS 根目录,它只返回一个 FileSystemDirectoryHandle —— 而这个 handle 必须由用户主动授予(通过 showDirectoryPicker())或由已持久化权限的已有句柄恢复得到。OPFS 的根目录没有“默认可获取”的路径或别名,浏览器刻意不暴露自动可读写的根入口,这是安全模型的核心设计。
正确获取 OPFS 根目录的唯一方式:showDirectoryPicker + 持久化权限
你必须让用户点击选择一个空文件夹(推荐新建专用文件夹),再调用 requestPermission({mode: 'readwrite'}) 并持久化,之后才能把它当作“逻辑上的 OPFS 根”来使用。常见错误是跳过用户手势或试图绕过 picker:
- 直接调用
navigator.storage.getDirectory()不带参数 → 返回的是当前 origin 的“默认存储位置”,不是 OPFS,且不可写(Chrome 中甚至抛出NotAllowedError) - 在非用户手势上下文(比如 setTimeout、fetch 回调)中调用
showDirectoryPicker()→ 立即被拒绝,报错DOMException: Permission denied - 未调用
handle.requestPermission({mode: 'readwrite'})或未检查返回值为'granted'→ 后续getFileHandle()或getDirectoryHandle()会失败 - 没调用
navigator.storage.persist()或忽略其返回的false→ 页面刷新后权限丢失,handle 无法复用
典型可用流程(含错误防护)
以下代码片段展示了最小可行路径,重点在于顺序和错误检查:
async function initOPFSRoot() {
try {
// 1. 必须由用户点击触发
const handle = await window.showDirectoryPicker();
// 2. 显式请求读写权限(不能省略)
const permission = await handle.requestPermission({ mode: 'readwrite' });
if (permission !== 'granted') throw new Error('Permission denied');
// 3. 尝试持久化(非强制但强烈建议)
const persisted = await navigator.storage.persist();
if (!persisted) console.warn('Storage not persisted — permission may reset on reload');
// 4. 现在 handle 就是你能稳定使用的“OPFS 根”
return handle;
} catch (err) {
// 常见 err.name:AbortError(用户取消)、NotAllowedError(非手势)、SecurityError(跨域 iframe)
console.error('OPFS root setup failed:', err);
}
}
为什么不能用 getDirectory() 替代 showDirectoryPicker()?
navigator.storage.getDirectory() 在当前规范中仅用于获取当前 origin 的“默认存储目录”(如 Chrome 中对应 IndexedDB 所在沙盒路径),它与 OPFS 完全无关。它的行为不稳定且无标准定义:
- Chrome 117+ 中调用会直接抛出
TypeError: Illegal invocation(除非传入{type: 'temporary'},但该选项已被废弃) - Firefox 和 Safari 尚未实现该方法,调用即
undefined - 即使某版本返回了 handle,它也不具备 OPFS 的原子写、流式写、
createSyncAccessHandle等关键能力
真正需要 OPFS 特性时,showDirectoryPicker() 是唯一标准路径。别指望“静默初始化”——用户必须明确授权一次,后续才能免交互复用句柄。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











