createSyncAccessHandle 在 Worker 中根本不可用,该 API 已被 Chrome 122+ 等主流浏览器彻底移除,Worker 中仅支持通过主线程传入 FileSystemFileHandle 后异步调用 createWritable() 写入文件。

createSyncAccessHandle 在 Worker 中根本不可用,所有试图调用它的代码都会报 TypeError: root.createSyncAccessHandle is not a function。这不是兼容性问题,而是该 API 已被 Chrome 122+、Edge 122+ 等主流浏览器彻底移除 —— 它从未在 Worker 环境中实现过,也永远不会支持。
Worker 中根本不存在 createSyncAccessHandle
很多人看到 FileSystemSyncAccessHandle 这个类名,就误以为能通过 createSyncAccessHandle() 获取同步句柄。但事实是:这个方法只在极早期 Chromium 实验版本中短暂存在过,2023 年底已被正式废弃,2026 年所有稳定版浏览器均已删除其定义。Worker 的 JS 上下文里连这个函数的影子都没有。
-
root.createSyncAccessHandle调用必然失败,且无法 polyfill 模拟 - 同步 I/O 与 Worker 的非阻塞设计目标冲突,浏览器主动拒绝提供该能力
- 即使主线程能拿到
FileSystemFileHandle,也无法在 Worker 内“转换”成同步句柄
Worker 中唯一合法的 OPFS 文件写入路径
Worker 必须依赖主线程传递已授权的 FileSystemFileHandle,再走异步 createWritable() 流程。这不是妥协,而是当前标准下唯一安全、可靠、可落地的方式。
- 主线程必须用
worker.postMessage({ type: 'init', handle: file }, [file])传入句柄,[file]是必需的 transferable 参数,漏掉会触发DataCloneError - Worker 内不能调用
window.storage.getDirectory()—— 该方法仅限主线程安全上下文 - 每次写入都应新建
createWritable()流,不要复用或缓存流对象;流生命周期内可多次write(),但必须以close()结束 - 漏掉
await writable.close()是最常见错误:数据停留在缓冲区,文件内容为空或截断
write() 方法的参数和编码陷阱
write() 不接受字符串字面量,也不接受普通对象。它只认 ArrayBuffer、TypedArray(如 Uint8Array)和 Blob。传错类型不会报错,但写入静默失败或抛出类型错误。
立即学习“前端免费学习笔记(深入)”;
- 写字符串必须先用
new TextEncoder().encode('hello')→ 得到Uint8Array - 写 Blob 需要
await blob.arrayBuffer(),不能直接传blob -
write(data, { at: 1024 })可随机写入,但at是字节偏移量,UTF-8 中中文字符占 3 字节,不能用str.length计算 - 不带
{ at }时,写入位置由流内部指针维护:首次从 0 开始,后续接续上一次末尾(类似追加)
为什么你总想“同步”,但实际必须接受异步语义
OPFS 在 Worker 中的设计哲学就是:用可控的异步链路替代不可靠的同步阻塞。所谓“近似同步”,靠的是明确的 await 顺序和 close 保障,而不是绕开事件循环。
- 主线程传句柄 + Worker 内
await createWritable()+await write()+await close()构成原子写入单元 - 若需多段写入,应在同一
createWritable()返回的流上连续write(),而非反复开关流 - Worker 生命周期结束前未
close(),数据一定丢失 —— 这不是 bug,是 OPFS 的原子提交设计
真正容易被忽略的,不是怎么写,而是写完之后那一行 await writable.close() —— 它不在语法高亮里,不报错,却决定数据是否真正落盘。



















