跨源隔离:响应头、SharedArrayBuffer 与部署检查
了解跨源隔离会改变什么、COOP 与 COEP 如何协作,以及启用 SharedArrayBuffer 前如何验证嵌入资源。
BotBrowser Team
跨源隔离是浏览器根据兼容的响应策略和文档关系建立的一种安全状态。它可以在受支持的浏览器中启用 SharedArrayBuffer 等 Web 功能,但不会让所有跨源资源自动可用。常见的顶层部署会同时配置 Cross-Origin-Opener-Policy: same-origin(COOP)和 Cross-Origin-Embedder-Policy(COEP),后者可使用 require-corp,也可在支持且适用时使用 credentialless。随后页面可读取 window.crossOriginIsolated,确认浏览器最终建立的状态。
部署决策远不止“添加两个响应头”。COOP 会改变页面与跨源窗口的关系;COEP 会改变嵌入式跨源资源的加载条件。它们可能影响登录弹窗、支付、分析、媒体、字体、frame 和第三方脚本。启用依赖隔离功能的代码前,应盘点这些依赖,检查实际响应头,并分阶段部署策略,同时准备明确的回退与回滚方案。跨源隔离是具有兼容性成本的应用架构选择。
跨源隔离改变什么
WHATWG HTML 规范中的跨源隔离模型描述的是浏览器状态,不是网络隧道,也不是脚本可以自行设置的属性。页面选择与其他浏览上下文及嵌入资源建立更严格的关系。如果浏览器接受适用策略与文档关系要求,就会通过 crossOriginIsolated 暴露最终状态。因此,记录这个运行时结果很重要;服务器返回一个响应头本身并不能证明加载后的文档已经隔离。
“跨源”表示 scheme、host 或 port 不同。即使组织同时拥有两个子域,它们仍可能是不同来源。来源边界与站点边界不同,CDN 主机、静态资源域或客户托管的 frame 都可能改变适用策略。本地开发时能够加载的资源,在生产环境中可能具有不同的来源和响应配置。
跨源隔离常与 SharedArrayBuffer 一起讨论,但这只是一个用途。应用可能需要它来支持特定库或运行时能力。不同浏览器和平台版本的准确可用条件可能有所差异;安全上下文和隔离文档是常见前提,但不保证所有环境都公开所有功能。应查看具体 API 的支持信息并测试已部署文档。不能仅凭 User-Agent 字符串或响应头存在就推断功能可用。
window.crossOriginIsolated 告诉应用当前全局环境是否被浏览器视为已隔离,但不会指出是哪一个响应头或嵌入资源阻止了隔离。实用的诊断记录应同时包含最终文档 URL、相关响应头、浏览器版本和受控资源清单。报告聚焦配置事实即可,无须采集用户数据或无关浏览器属性。
COOP 与 COEP 的职责不同
COOP 控制文档与顶层浏览上下文的关系,包括 opener 关系。设置 Cross-Origin-Opener-Policy: same-origin 后,在相关情形中,页面会与跨源文档分入隔离的浏览上下文组。这能加强窗口之间的隔离,但也可能改变依赖 window.opener 的流程,例如登录弹窗向发起页面返回结果的方式。MDN COOP 参考说明了策略值及其影响。应实际测试弹窗登录、支付和支持流程,不要假设这些集成毫无影响。
COEP 控制文档嵌入的跨源资源能否加载。使用 Cross-Origin-Embedder-Policy: require-corp 时,跨源资源通常需要通过 CORS 请求并收到成功的 CORS 响应,或者以兼容的 Cross-Origin-Resource-Policy(CORP)响应提供。过去通过 no-CORS 请求加载的资源,如果没有明确允许嵌入,可能被阻止。资源所有者或 CDN 可能需要在 CORS 响应中返回 Access-Control-Allow-Origin,或为符合条件的 no-CORS 资源返回适当的 Cross-Origin-Resource-Policy。正确响应头取决于资源类型、凭据和预期共享边界。
credentialless COEP 模式可在适用的 no-CORS 资源请求中不要求 CORP,但会在这些请求中省略 Cookie 等凭据,从而改变请求行为。选择前应根据当前浏览器文档核实支持情况和详细行为。它不是通用兼容开关;需要身份验证的资源不适合采用这种方式。MDN 跨源隔离指南概述了策略组合及其应用影响。
两项策略互相补充。COOP 单独使用不会执行 COEP 的嵌入资源检查;在常见隔离部署中,COEP 单独使用也不会建立所需的顶层分离。页面最终是否隔离,取决于完整策略和文档关系,而不是手动设置某个属性。不要为了让一个供应商脚本加载而全局放宽策略;应识别资源、确认负责人,并选择符合预期访问范围的 CORS、CORP、代理或替代集成。
嵌入资源与来源边界
配置 COEP 前,盘点页面可能嵌入或请求的所有资源:脚本、样式表、字体、图片、音频、视频、Worker、嵌套 frame 以及第三方代码加载的资源。将每一项分类为同源、跨源 CORS、跨源 CORP,或无法满足所选策略的集成。检查暂存环境中的真实网络响应。资源 URL 本身无法说明响应是否带有必需头部、重定向是否改变来源,或带凭据请求是否具有兼容的 CORS 响应。
可用以下兼容性表为每项依赖指定负责人和决策:
| 依赖情形 | 检查证据 | 部署决策 |
|---|---|---|
| 同源应用资源 | 最终 URL 和响应状态 | 保持同源,并确认重定向仍在预期范围 |
| 计划公开使用的跨源资源 | CORS 模式与 Access-Control-Allow-Origin,或适当的 CORP 响应 | 与资源负责人约定配置并测试真实响应 |
| 需要凭据的跨源请求 | 凭据模式、精确允许来源和凭据响应头 | 定义明确的 CORS 合同,不以 credentialless 代替 |
| 供应商资源无法选择加入 | 负责人、用途及其是否为必要功能 | 替换、按批准设计代理、延后,或保留非隔离回退 |
| 弹窗或跨源 frame 流程 | opener 行为、frame 来源和策略关系 | 在目标策略下测试完整用户流程 |
跨源 iframe 是具有独立来源和策略关系的文档。不要假设顶层页面的 crossOriginIsolated 值会自动描述每个子 frame,或自动授予子文档所有能力。应确认目标功能的嵌入规则及必要委派,并在夹具中记录预期来源后检查子文档自己的运行时状态。frame 本身也可能需要兼容的响应策略。如果不拥有该 frame,应先与其负责人协调,再依赖其中只能在隔离环境使用的功能。
策略应遵循最小权限原则,只允许应用所需的来源和资源类型,避免第三方集成悄然扩大访问范围。对公开且不带凭据的资源,通配符 CORS 响应有时是合适的,但不能通用于经过身份验证的数据。CORP 值也会表达谁可以嵌入响应;应选择符合预期关系的值,而非默认采用最宽泛范围。页面、CDN、身份提供方和嵌入服务可能由不同团队管理,应为每个响应头记录负责人。
确定性的部署夹具
以下夹具将隔离状态显示给用户,使用测试用例提供的预期值进行断言,并确保即使断言或报告步骤失败也会清理临时 DOM。应在应用相同来源、相同响应头路径下提供夹具。在目标隔离环境中配置预期值 true;在缺少完整策略的对照环境中,单独声明相应预期。不要从被测值本身推导预期。
async function checkIsolation(expected) {
const host = document.createElement('section');
const status = document.createElement('output');
status.setAttribute('aria-live', 'polite');
host.append(status);
document.body.append(host);
try {
const isolated = window.crossOriginIsolated === true;
const sharedMemoryAvailable = typeof SharedArrayBuffer === 'function';
const passed = expected ? isolated && sharedMemoryAvailable : isolated === expected;
status.textContent = `${passed ? 'PASS' : 'FAIL'}: isolated=${isolated}; SharedArrayBuffer=${sharedMemoryAvailable}`;
console.assert(passed, status.textContent);
if (expected) console.assert(sharedMemoryAvailable, 'Expected SharedArrayBuffer in this declared browser case');
return { passed, isolated, sharedMemoryAvailable, visibleResult: status.textContent };
} finally {
host.remove();
}
}
// 此预期由候选来源对应的测试配置声明。
await checkIsolation(true);
夹具分别报告两个事实:浏览器隔离状态,以及当前环境是否公开 SharedArrayBuffer。在明确支持的浏览器情形中可以同时断言两者;对于不在应用支持范围内的浏览器,应记录 API 不可用并验证产品回退。回退测试应作为独立预期结果,不能重新标记成隔离通过。此代码不分配共享内存、不启动 Worker,也不进行测量;目的只是验证响应配置和运行时资格。
要验证资源兼容性,可以提供一个自有的小页面,从每个必需类别加载一个代表性跨源资源。为每项资源准备稳定的夹具 URL,并断言用户可见的加载或失败状态。每种策略情形使用独立夹具,避免一个字体失败掩盖脚本或 frame 的结果。只有在生产依赖确实使用重定向或凭据时才纳入这些行为。teardown 阶段移除夹具节点并关闭隔离测试上下文,不要修改共享的生产数据。
部署、监控与回滚
分阶段发布。先盘点跨源依赖并确认资源负责人;再为暂存来源配置 COOP 和选定的 COEP 值,运行夹具及完整应用流程。应检查最终文档响应上的响应头,而不只是负载均衡器或源代码配置文件,因为重定向、CDN 规则、Service Worker 和主机级路由都可能改变实际响应。在真实页面导航后确认 crossOriginIsolated,并按照生产请求模式测试每项必要资源。
大范围发布前,测试跨浏览上下文流程:弹窗认证、支付交接、客户 frame、帮助组件以及任何依赖 opener 引用的集成。还应在支持范围边界的浏览器版本中测试,并覆盖使用回退的对照情形。保留简短报告,记录最终 URL、浏览器构建、COOP/COEP 值、隔离布尔值、资源失败、frame 来源和用户可见结果。报告中不要保留秘密、账户数据或无关配置文件信息。
只有在预期页面观察到隔离状态、必要资源在声明策略下可加载,并且功能不可用时用户仍能完成核心任务,发布才算通过。如果供应商资源阻止发布,应保留回退或替换集成,不要未经记录就全局放宽策略。把隔离失败作为需要诊断的配置结果,而不是悄悄修改断言的理由。
修改生产响应头前应准备回滚。保留原响应策略和应用版本。如果新策略破坏必要集成,应一起恢复已知正常的策略与应用路径,然后用同一夹具验证预期的非隔离状态和回退。回滚版本应删除依赖隔离专属功能的路径,或通过运行时检查保护它们。保留传输安全及其他安全响应头;回滚不能成为通过 HTTP 提供内容或抹去测试证据的理由。
BotBrowser 可以验证什么
BotBrowser 支持使用受控浏览器上下文执行获授权的应用 QA。团队可以用隔离上下文在声明的浏览器构建上运行自有夹具,验证页面运行时隔离状态,并比较用户可见的回退行为,避免无关流程遗留的状态影响结果。BotBrowser 多账户隔离文档介绍了为独立会话使用不同浏览器上下文。这有助于让测试环境可重复,但不会替网站配置响应头。
BotBrowser 无法让文档获得跨源隔离、提供 COOP 或 COEP 响应头、改变第三方资源的 CORS/CORP 响应、保留策略有意分离的弹窗行为,也不能保证所有平台都支持 SharedArrayBuffer。WHATWG HTML 跨源隔离模型及网站所有者的部署配置仍是依据。BotBrowser 可用于观察记录条件下的浏览器流程;资源合同、策略选择、兼容性和回滚仍由应用与基础设施负责人承担。
相关内容包括浏览器版本验证指南、安全上下文指南和浏览器 API 兼容性指南。它们讨论版本证据、安全上下文资格和 API 回退规划;本文聚焦跨源隔离需要的响应策略与资源变更。
请在发布记录中注明每项策略和资源契约的负责人。这样后续回滚时可以复核:团队能够区分文档响应头、重定向、CDN 响应或嵌入依赖的变化。记录应只保留技术响应和可见结果,并在每次策略变更后重复相同检查。