跨域隔离检测
输入任意网站的网址,查看它是否启用了跨域隔离,以及 SharedArrayBuffer 和多线程 WebAssembly 能否在那里运行。检测工具会读取该网址的 Cross-Origin-Opener-Policy 和 Cross-Origin-Embedder-Policy 响应头,并告诉你缺少了什么。它只读取响应头,不会获取或存储其他任何内容。
为什么跨域隔离对网页游戏很重要
一些非常有用的浏览器能力被锁在跨域隔离之后,对游戏来说最关键的就是 SharedArrayBuffer,也就是让多线程 WebAssembly 成为可能的共享内存。如果你的引擎发布了多线程网页构建,没有它就无法运行:
- Godot 的网页导出过去一直需要 SharedArrayBuffer(Godot 4.3+ 新增了单线程导出,以避免使用这些响应头)。
- Unity 的多线程 WebGL 构建需要它。
- Emscripten pthreads、ffmpeg.wasm 以及许多物理和编解码库也需要它。
没有隔离,浏览器还会停用高精度计时器和 performance.measureUserAgentSpecificMemory()。所以如果多线程游戏悄无声息地加载失败,或者 performance.now() 的精度看起来异常粗糙,隔离检测就是首先要做的事。
跨域隔离的工作原理
当页面在 HTML 文档上发送以下两个响应头时,它就成为跨域隔离的页面:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corpCOOP: same-origin 会把页面与其他非同源的窗口切断联系。COEP: require-corp 表示每个子资源都必须显式选择加入才能被嵌入。当两者都设置好后,self.crossOriginIsolated 会变为 true,SharedArrayBuffer 也随之解锁。
难点在于 COEP:一旦开启,每个跨域资源(CDN 图片、字体、脚本、iframe)都必须发送 Cross-Origin-Resource-Policy: cross-origin,或者通过 CORS 获取,否则浏览器会将其阻止。这通常就是站点出问题的地方。如果你无法控制自己的第三方资源,可以改用 Cross-Origin-Embedder-Policy: credentialless,它会以不带凭据的方式加载跨域资源,而不要求它们选择加入。
如何启用
Cloudflare Pages(一个 _headers 文件):
/*
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corpVite 开发服务器(vite.config.js):
export default {
server: {
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
},
},
}nginx:
add_header Cross-Origin-Opener-Policy same-origin;
add_header Cross-Origin-Embedder-Policy require-corp;itch.io:在你的 HTML 游戏嵌入选项中启用 “SharedArrayBuffer support”,它会替你设置好这些响应头。
部署后,重新加载并重新运行检测工具。crossOriginIsolated 应该会翻转为 true。
常见问题
如何检查我的页面是否启用了跨域隔离?
在上面的检测工具中输入你网站的网址。它会在服务端读取页面的 Cross-Origin-Opener-Policy 和 Cross-Origin-Embedder-Policy 响应头,并告诉你这种组合是否让页面实现了隔离。如果想在自己的浏览器中做运行时检查,可以打开页面并在控制台中运行 crossOriginIsolated,当隔离生效时它会返回 true。
为什么 SharedArrayBuffer 是 undefined?
浏览器只向跨域隔离的页面暴露 SharedArrayBuffer。如果它是 undefined,说明你的页面缺少 Cross-Origin-Opener-Policy: same-origin 和 Cross-Origin-Embedder-Policy: require-corp 响应头,或者某个跨域资源在 COEP 下阻止了隔离。设置好这些响应头(见上文)并重新测试。
COOP 和 COEP 是什么?
Cross-Origin-Opener-Policy(COOP)控制页面如何与其他浏览窗口交互。Cross-Origin-Embedder-Policy(COEP)控制哪些子资源可以被嵌入。把 COOP: same-origin 和 COEP: require-corp 一起设置,会让页面实现跨域隔离,从而解锁 SharedArrayBuffer 和其他强大功能。
我的 WebAssembly 游戏在浏览器里加载不出来,是这个原因吗?
通常是的。多线程 WebAssembly 构建(某些 Godot 和 Unity 网页导出、Emscripten pthreads、ffmpeg.wasm)需要 SharedArrayBuffer,而它需要跨域隔离。如果上面的检测工具显示 “未配置跨域隔离”,请设置 COOP/COEP 响应头,或者在可行的情况下改用引擎的单线程构建。
我需要 Cross-Origin-Resource-Policy 响应头吗?
在你要隔离的页面上不需要。让文档实现跨域隔离的是 COOP 和 COEP,它们放在文档上。Cross-Origin-Resource-Policy(CORP)是一个方向相反的不同响应头:你把它放在某个跨域资源(图片、字体或脚本)上,这样使用 COEP: require-corp 的页面才被允许嵌入它。所以如果检测工具在你的页面上显示 CORP “未设置”,那是预期之内、完全正常的。你只需要给其他隔离页面需要加载的资源添加 CORP。
启用 COEP 会破坏我的第三方嵌入内容吗?
有可能。开启 COEP: require-corp 后,每个跨域资源都必须发送 Cross-Origin-Resource-Policy 或使用 CORS,否则就会被阻止。如果你嵌入了无法控制的 CDN 资源或第三方脚本,可以改用 COEP: credentialless,从而避免这一要求。
相关内容
- COOP/COEP 与 SharedArrayBuffer:包含代码的完整教程
- WebGL 与 WebGPU 检测:测试你浏览器的 GPU 能力
- 用于游戏逻辑的 Web Worker:把工作移出主线程
- 2026 年最佳网页游戏引擎:哪些引擎需要线程
- Cinevva 引擎:我们以网页为先的引擎