使用 COOP 和 COEP“跨源隔离”网站
使用 COOP 和 COEP 设置跨源隔离环境并启用
强大的功能,如“SharedArrayBuffer”、“performance.measureUserAgentSpecificMemory()”以及更高精度的高解析性能计时器。
更新
- 2021 年 8 月 5 日:JS Self-Profiling API 被列为需要跨源隔离的 API 之一,但反映最新方向变化的内容已被删除。
- 2021 年 5 月 6 日:根据反馈和报告的问题,我们决定调整在 Chrome M92 中限制的非跨源隔离站点中
SharedArrayBuffer
用法的时间表。 - 2021 年 4 月 16 日:添加了关于新的 COEP 无凭据模式和 COOP 同源允许弹出窗口(作为跨源隔离宽松条件)的注释。
- 2021 年 3 月 5 日:删除了对
SharedArrayBuffer
、performance.measureUserAgentSpecificMemory()
和调试功能的限制。现在,Chrome 89 中已完全启用这些功能。添加了即将推出的功能performance.now()
和performance.timeOrigin
,新功能具有更高的精度。 - 2021 年 2 月 19 日:在 DevTools 上添加了关于功能策略
allow="cross-origin-isolated"
和调试功能的注释。 - 2020 年 10 月 15 日:Chrome 87 中已提供
self.crossOriginIsolated
。为了反映这一点,self.crossOriginIsolated
返回true
时,document.domain
不可变。performance.measureUserAgentSpecificMemory()
正在结束来源试验,在 Chrome 89 中将默认启用。Chrome 88 中将提供 Android 版 Chrome 上的共享数组缓冲区。
某些 Web API 会导致 Spectre 等旁道攻击的风险增加。为了减轻这种风险,浏览器提供了一个基于选择加入的隔离环境,称为“跨源隔离”。在跨源隔离状态下,网页能够使用特权功能,包括:
API | 描述 |
---|---|
SharedArrayBuffer | WebAssembly 线程需要。Android 版 Chrome 88 中提供了此 API。桌面版目前在站点隔离的帮助下默认启用,但需要跨源隔离状态,并且在 Chrome 92 中默认禁用。 |
performance.measureUserAgentSpecificMemory() | Chrome 89 中提供。 |
performance.now() , performance.timeOrigin | 目前已在许多浏览器中提供,解析时间限制为 100 微秒或更短。通过跨源隔离,解析时间可以达到 5 微秒或更短。 |
跨源隔离状态还可以防止修改 document.domain
。(如果能够修改 document.domain
,则允许同站文档之间相互通信,这是同源策略中的一个漏洞。)
要选择跨源隔离状态,您需要在主文档上发送以下 HTTP 标头:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
这些标头指示浏览器阻止加载未选择由跨源文档加载的资源或 iframe,并防止跨源窗口直接与您的文档交互。这也意味着跨源加载的资源需要选择加入。
通过检查 self.crossOriginIsolated
来确定网页是否处于跨源隔离状态。
本文介绍了如何使用这些新标头。在后续文章中中,我会提供更多背景和上下文。
通过部署 COOP 和 COEP 来让网站跨源隔离 #
整合 COOP 和 COEP #
1. 在顶级文档上设置 Cross-Origin-Opener-Policy: same-origin
#
通过在顶级文档上启用 COOP: same-origin
,则除非位于具有相同 COOP 设置的相同源中,否则同源窗口和从该文档打开的窗口将具有单独的浏览上下文组。因此,对打开的窗口强制执行隔离,同时禁止两个窗口相互通信。
浏览上下文组是一组共享相同上下文的选项卡、窗口或 iframe。例如,如果网站 (https://a.example
) 打开一个弹出窗口 (https://b.example
),打开程序窗口和弹出窗口共享相同的浏览上下文,并且它们可以通过 DOM API (window.opener
) 相互进行访问。

您可以从 DevTools 检查窗口打开程序及其 openee 是否位于单独的浏览器上下文组中。
2. 确保资源已启用 CORP 或 CORS #
确保页面中的所有资源都已加载 CORP 或 CORS HTTP 标头。第四步:启用 COEP 将需要此步骤。
根据资源的性质,您需要执行以下操作:
- 如果预计仅从相同来源加载资源,请设置
Cross-Origin-Resource-Policy: same-origin
标头。 - 如果预计仅从同一站点跨源加载资源,请设置
Cross-Origin-Resource-Policy: same-site
标头。 - 如果是从您控制的跨源加载资源,则要尽可能设置
Cross-Origin-Resource-Policy: cross-origin
标头。 - 对于您无法控制的跨源资源:
- 如果使用 CORS 提供资源,请在加载 HTML 标记中使用
crossorigin
(例如,<img src="***" crossorigin>
。) - 要求资源所有者支持 CORS 或 CORP。
- 如果使用 CORS 提供资源,请在加载 HTML 标记中使用
- 对于 iframe,请使用 CORP 和 COEP 标头,如下所示:
Cross-Origin-Resource-Policy: same-origin
(或根据上下文使用same-site
或cross-origin
)和Cross-Origin-Embedder-Policy: require-corp
。
3. 使用 COEP 仅报告 HTTP 标头评估嵌入资源 #
在完全启用 COEP 之前,您可以使用 Cross-Origin-Embedder-Policy-Report-Only
标头进行试运行,检查策略是否确实有效。您将收到不阻止嵌入内容的报告。以递归方式将其应用到所有文档。有关“仅报告 HTTP 标头”的信息,请参阅使用报告 API 观察问题。
4. 启用 COEP #
确认一切正常且可以成功加载所有资源后,请将 Cross-Origin-Embedder-Policy: require-corp
HTTP 标头应用到所有文档(包括通过 iframe 嵌入的文档)。
利用 self.crossOriginIsolated
确定隔离是否成功 #
当网页处于跨源隔离状态且所有资源和窗口在同一浏览上下文组中隔离时,self.crossOriginIsolated
属性会返回 true
。您可以使用此 API 来确定是否已成功隔离浏览上下文组,并获得对 performance.measureUserAgentSpecificMemory()
等强大功能的访问权限。
使用 Chrome DevTools 调试问题 #
对于在屏幕上呈现的资源(例如图像),很容易检测 COEP 问题,因为请求会被阻止且页面会指示缺少图像。但是,对于不一定具有视觉影响的资源(例如脚本或样式),可能无法注意到 COEP 问题。对于这些问题,请使用“DevTools 网络”面板。如果 COEP 有问题,您会在状态栏看到 (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep)
。
随后,您可以单击此条目以查看更多详细信息。
您还可以通过应用程序面板确定 iframe 和弹出窗口的状态。转到左侧的“框架”部分并展开“顶部”即可查看详细资源结构。
您可以检查 iframe 的状态,例如“SharedArrayBuffer”的可用性等。
您还可以检查弹出窗口的状态,例如它是否已跨源隔离。
使用报告 API 观察问题 #
报告 API 是另一种可以检测各种问题的机制。您可以配置报告 API 来指示用户浏览器在 COEP 阻止加载资源或 COOP 隔离弹出窗口时发送报告。从 69 版本开始,Chrome 就支持将报告 API 用于各种用途,包括 COEP 和 COOP。
要了解如何配置报告 API 和设置服务器以接收报告,请转到使用报告 API。
COEP 报告示例 #
当跨源资源被阻止时,示例 COEP 报告内容如下所示:
[{
"age": 25101,
"body": {
"blocked-url": "https://third-party-test.glitch.me/check.svg?",
"blockedURL": "https://third-party-test.glitch.me/check.svg?",
"destination": "image",
"disposition": "enforce",
"type": "corp"
},
"type": "coep",
"url": "https://cross-origin-isolation.glitch.me/?coep=require-corp&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4249.0 Safari/537.36"
}]
COOP 报告示例 #
当弹出窗口被隔离打开时,示例 COOP 报告内容如下所示:
[{
"age": 7,
"body": {
"disposition": "enforce",
"effectivePolicy": "same-origin",
"nextResponseURL": "https://third-party-test.glitch.me/popup?report-only&coop=same-origin&",
"type": "navigation-from-response"
},
"type": "coop",
"url": "https://cross-origin-isolation.glitch.me/coop?coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]
当不同的浏览上下文组尝试相互访问时(仅在“仅报告”模式下),COOP 也会发送报告。 postMessage()
时的报告如下所示:
[{
"age": 51785,
"body": {
"columnNumber": 18,
"disposition": "reporting",
"effectivePolicy": "same-origin",
"lineNumber": 83,
"property": "postMessage",
"sourceFile": "https://cross-origin-isolation.glitch.me/popup.js",
"type": "access-from-coop-page-to-openee"
},
"type": "coop",
"url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
},
{
"age": 51785,
"body": {
"disposition": "reporting",
"effectivePolicy": "same-origin",
"property": "postMessage",
"type": "access-to-coop-page-from-openee"
},
"type": "coop",
"url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]
总结 #
使用 COOP 和 COEP HTTP 标头的组合将网页选择加入特定跨源隔离状态。您将能够检查 self.crossOriginIsolated
,从而确定网页是否处于跨源隔离状态。
随着新功能可用于这种跨源隔离状态,我们将不断更新此帖子,并继续围绕 COOP 和 COEP 对 DevTools 进行改进。
资源 #
- 为何需要“跨源隔离”才能获得强大的功能
- 跨源隔离的启用指南
- Android 版 Chrome 88 和桌面版 Chrome 92 中的 SharedArrayBuffer 更新
- 利用
measureUserAgentSpecificMemory()
监控网页的总内存使用量