querypermission 是最轻量可靠的文件权限校验方式,按需分阶段检查读/写权限,结合 persisted 可跨会话复用授权,目录操作需更谨慎控制权限范围。

直接用 queryPermission 检查权限状态,再按需申请,是控制文件操作生命周期最轻量也最可靠的方式。它不依赖用户反复点选,也不硬编码“必须写”,而是让读、写、保存各环节按真实需要触发权限校验。
判断当前句柄是否具备指定访问能力
queryPermission() 返回 'granted'、'denied' 或 'prompt',反映浏览器对当前句柄的实时授权状态。注意它只查已有句柄,不自动弹窗——这是和 requestPermission() 的关键区别。
- 读操作前可只查
{ mode: 'read' },避免过早申请写权限 - 写入前必须查
{ mode: 'readwrite' },即使之前读过同一文件 - 若返回
'denied',说明用户明确拒绝过,再次调用requestPermission()通常无效,应引导用户手动重授(如通过系统设置)
读-改-存流程中分阶段校验权限
一个编辑场景里,读取时只需读权限,保存时才真正需要写权限。把权限检查拆到动作发生前,既减少打扰,也符合最小权限原则。
- 打开文件后,先
await handle.queryPermission({ mode: 'read' })确保能读 - 用户点击“保存”时,再
await handle.queryPermission({ mode: 'readwrite' }) - 若未获授权,立即
await handle.requestPermission({ mode: 'readwrite' })并检查结果 - 失败则提示“请在弹出窗口中允许修改此文件”,不中断编辑界面
结合 persisted 实现跨会话权限复用
用户授权后调用 handle.requestPermission({ mode: 'readwrite', persisted: true }),再将句柄存入 IndexedDB。下次启动时取出句柄,先 queryPermission —— 若仍为 'granted',即可跳过弹窗直接操作。
- 不是所有浏览器都默认持久化,
persisted: true是显式启用开关 - 用户可在浏览器设置中随时撤销,所以每次使用前仍须
queryPermission校验 - IndexedDB 中只存句柄(
self.handle),不存文件内容,兼顾隐私与效率
目录句柄的权限管理更需谨慎
目录句柄的 queryPermission 行为与文件句柄一致,但影响范围更大:一次授权可能覆盖整个子树。因此建议:
- 遍历目录仅用
mode: 'read'权限,避免误触发写请求 - 对特定子文件执行写操作时,单独获取其
FileSystemFileHandle并单独申请权限 - 删除或重命名操作必须走
mode: 'readwrite'校验,不可复用只读句柄










