SharedArrayBuffer 在浏览器中默认禁用,需启用跨域隔离(COEP+COOP 响应头)且页面无非同源资源才能使用;必须由主线程创建并 transfer 给 Worker,配合 Atomics 实现线程安全共享内存。

SharedArrayBuffer 在 HTML 中根本不能直接用
浏览器默认禁用 SharedArrayBuffer,哪怕你写了 new SharedArrayBuffer(1024),也会立刻抛出 ReferenceError: SharedArrayBuffer is not defined。这不是代码写错了,是浏览器主动屏蔽——因为 Spectre 漏洞后,所有主流浏览器(Chrome 91+、Firefox 93+、Safari 15.4+)都要求必须启用跨域隔离(Cross-Origin Isolation)才能使用它。
必须开启 cross-origin isolation 才能启用 SharedArrayBuffer
光在 HTML 里加 <meta> 或改响应头是没用的,关键得让整个页面满足跨域隔离条件。这需要两步同时生效:
- 服务器必须返回两个响应头:
Cross-Origin-Embedder-Policy: require-corp和Cross-Origin-Opener-Policy: same-origin - HTML 页面本身不能通过
<script src="http://third-party.com/lib.js"></script>或<img src="https://cdn.example.com/a.png" alt="HTML怎么做SharedArrayBuffer_HTML SharedArrayBuffer共享内存【技巧】" >加载任何非同源资源(否则 COEP 会失败,页面直接白屏) - 本地
file://协议下永远不生效,必须走http://或https://(推荐用npx serve或 VS Code Live Server 启动)
检查是否成功:打开 DevTools → Application → Frames → 查看右侧 “Cross-Origin Isolation” 状态是否为 “true”。如果不是,SharedArrayBuffer 依然不可用。
Worker 中使用 SharedArrayBuffer 的典型模式
SharedArrayBuffer 几乎只在主线程 + Worker 组合中实用,比如音视频处理、物理模拟、多线程计算。主线程创建缓冲区,然后传给 Worker,双方通过 Atomics 同步:
立即学习“前端免费学习笔记(深入)”;
const sab = new SharedArrayBuffer(1024);
const i32 = new Int32Array(sab);
// 主线程发给 Worker
worker.postMessage({sab}, [sab]); // 注意:必须 transfer,否则 Worker 收不到
// Worker 内
self.onmessage = ({data}) => {
const {sab} = data;
const i32 = new Int32Array(sab);
Atomics.add(i32, 0, 1); // 安全写入
};
常见错误:
- 忘了在
postMessage第二个参数里写[sab]—— 缓冲区不会被传输,Worker 收到的是null - 在 Worker 里直接
new SharedArrayBuffer()—— 行不通,必须由主线程创建并 transfer 过来 - 用
ArrayBuffer替代SharedArrayBuffer后调Atomics—— 会报TypeError: expected shared buffer
不是所有场景都需要 SharedArrayBuffer
如果你只是想在主线程和 Worker 之间传数据,postMessage 配合结构化克隆(如普通对象、ArrayBuffer)已经够快;只有当你需要频繁、细粒度、低延迟地读写同一块内存(比如每毫秒更新数千个粒子坐标),才值得上 SharedArrayBuffer + Atomics。而且它不支持 GC 自动管理,一旦忘记同步或越界访问,可能引发静默错误或数据竞争。
真正容易被忽略的点是:即使启用了跨域隔离,Safari 对 SharedArrayBuffer 的支持仍比 Chrome/Firefox 更保守(例如某些 iframe 场景下会静默降级),上线前务必在目标浏览器中用 typeof SharedArrayBuffer !== 'undefined' 做运行时检测并提供 fallback。



















