特定场景下使用getDirectoryHandle创建目录时触发DOMException异常问题
分析与临时解决建议
这确实是个挺棘手的边缘场景问题,结合你描述的细节和Demo,我给你梳理下可能的原因和临时处理方向:
核心问题拆解
你遇到的异常本质是Chromium拖拽获取的FileSystemDirectoryHandle缓存了过期的目录状态,和磁盘上实际的目录权限/状态不匹配,才会触发那句“缓存状态已更改”的错误。而且这个问题只在.local目录出现,结合你提到的lsd无法访问但ls、Nautilus可以的细节,说明.local目录可能有系统层面的特殊权限处理(比如隐藏的ACL规则,或者桌面环境的权限上下文),导致Chromium拖拽API的状态同步逻辑出了问题——而window.showDirectoryPicker()走的是系统原生文件选择器,能正确获取目录的最新状态,所以不会出错。
临时Workaround尝试
既然你已经提交了Chromium Bug报告,等待修复期间可以试试这两个临时方案:
1. 强制刷新权限状态
在调用getDirectoryHandle前,先主动校验并请求读写权限,这可能会刷新Chromium缓存的handle状态:
const handleHandle = async (handle) => { console.log(handle); // 先确认并获取读写权限 const currentPerm = await handle.queryPermission({ mode: "readwrite" }); if (currentPerm !== "granted") { await handle.requestPermission({ mode: "readwrite" }); } // 再尝试创建目录 try { const newDirHandle = await handle.getDirectoryHandle("never", { create: true }); console.log(newDirHandle); } catch (err) { console.error(err); } };
2. 针对.local目录做降级提示
如果上面的方法无效,可以在代码里判断拖拽的目录路径是否包含.local,如果是,提示用户改用按钮选择目录的方式:
addEventListener("drop", (e) => { e.preventDefault(); e.dataTransfer.items[0].getAsFileSystemHandle().then(async (handle) => { // 尝试获取目录路径(注意:仅在Chrome 102+支持,且需要权限) try { const path = await handle.resolve(); if (path.includes(".local")) { alert("检测到.local目录,暂时无法通过拖拽创建子目录,请使用下方按钮选择目录"); return; } } catch {} handleHandle(handle); }); });
额外说明
你提到lsd工具无法访问.local的细节也很关键,这说明.local目录的访问逻辑和普通目录有差异(可能是lsd没有适配Ubuntu用户目录的特殊权限上下文),这也解释了为什么Chromium的拖拽API会在这个目录上出问题——毕竟拖拽流程的权限处理和原生文件选择器是两套逻辑,更容易出现适配漏洞。
内容的提问来源于stack exchange,提问作者KTibow
相关产品推荐
相关产品推荐

