file system access api 必须在 https 或 localhost 下由用户手势触发,调用 showopenfilepicker() 获取 filesystemfilehandle 后需 getfile() 读取,createwritable() 写入后必须 close() 才生效。

不能直接用 HTML 标签或属性启用 File System Access API,它必须由 JavaScript 在用户点击等手势下主动调用,且只在 HTTPS 或 localhost 环境生效;window.showOpenFilePicker() 返回的是 FileSystemFileHandle 句柄,不是路径,也不支持自动读同目录其他文件。
必须满足的运行前提条件
API 不是“写了就能用”的功能,环境不合法会直接抛错:
-
SecurityError:页面运行在file://协议下(比如双击打开 HTML 文件),或嵌套在非安全上下文的 iframe 中 - HTTPS 是硬性要求,
http://127.0.0.1也不行,必须是https://或http://localhost - 所有调用必须由用户手势触发,例如
button.onclick、input.onchange,不能在DOMContentLoaded或setTimeout中自动执行 - Chrome/Edge 115+ 原生支持,Firefox 125+ 仅部分支持,Safari 完全未实现——别指望跨浏览器开箱即用
showOpenFilePicker() 之后怎么读内容
拿到句柄只是第一步,fileHandle.getFile() 返回的是只读 File 对象,和 <input type="file"> 的结果一致,不是可写通道:
对设计或页面进行 WCAG 2.1 AA 无障碍审计。触发关键词:“audit accessibility”、 “check a11y”、 “is this accessible?” 或在审查设计时使用。
- 必须显式调用
const file = await fileHandle.getFile()才能读取当前快照 -
file.text()、file.arrayBuffer()、file.stream()都可用,但它们不反映后续外部修改 - 常见错误:误以为
fileHandle本身能直接读,实际必须过getFile() - 若需实时感知文件变更(如被外部编辑器改了),得靠
fileHandle.queryPermission({ mode: 'readwrite' })+ 轮询或监听(目前无原生事件)
createWritable() 写入必须配 close()
这是最常踩的坑:调用了 write() 却没 close(),文件内容为空或残留旧数据:
-
const writable = await fileHandle.createWritable()打开的是流式写通道,不是覆盖写入命令 -
await writable.write('hello')只是把数据送进缓冲区,不落盘 - 必须
await writable.close()才真正提交并释放句柄;漏掉这步等于白写 - 追加内容要手动 seek:
await writable.write({ type: 'seek', position: file.size }),API 不提供append模式
如何安全保存而不覆盖误操作
用户点“保存”时,不能无脑复用原始句柄,尤其当文件可能已被外部程序修改:
- 首次打开建议用
showOpenFilePicker({ excludeAcceptAllOption: true }),避免用户误选“所有文件”导致权限过宽 - 保存时优先重用原
fileHandle,但需捕获NotAllowedError(用户取消授权)和NotFoundError(文件被删或移动) - 失败后 fallback 到
showSaveFilePicker()弹新对话框,而不是静默失败 - 句柄不可跨页面持久化存储,但可通过
structuredClone()传给 worker 或存入 IndexedDB(需配合queryPermission检查有效性)
真正麻烦的不是语法,而是权限状态的不确定性:用户可能中途撤销授权、文件可能被锁、句柄可能过期。每次写之前都应检查 await fileHandle.queryPermission({ mode: 'readwrite' }) === 'granted',别假设上次有效这次还有效。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










