使用 Origin-Agent-Cluster 标头请求性能隔离

一个新的 HTTP 响应标头,用于限制网域级脚本编写,并从浏览器请求专用资源。

Domenic Denicola
Domenic Denicola

Origin-Agent-Cluster 是一个新的 HTTP 响应标头,用于指示浏览器阻止同网站跨源网页之间的同步脚本访问。浏览器还可能会使用 Origin-Agent-Cluster 作为提示,表明您的源应获得自己的单独资源,例如专用进程。

浏览器兼容性

目前,Origin-Agent-Cluster 标头仅在 Chrome 88 及更高版本中实现。我们在设计该规范时与 Mozilla Firefox 的代表密切合作,他们认为该规范值得进行原型设计,并且 WebKit(Safari 使用的浏览器引擎)的代表对其给予了初步好评

不过,在此期间,您可以立即为所有用户部署 Origin-Agent-Cluster 头文件。不理解该属性的浏览器会直接忽略它。此外,与使用网站键(默认)的代理集群相比,使用来源键的代理集群中的网页实际上可以执行的操作更少,因此您无需担心互操作性问题。

浏览器无法自动分隔同源的原因

网络是基于同源政策构建的,该政策是一项安全功能,用于限制文档和脚本与其他来源的资源的互动方式。例如,托管在 https://a.example 的网页与托管在 https://b.examplehttps://sub.a.example 的网页位于不同的来源。

在后台,浏览器会以不同的方式使用来源提供的分离。以前,即使不同的来源无法访问彼此的数据,它们仍然会共享操作系统线程、进程和内存分配等资源。这意味着,如果一个标签页运行缓慢,则会拖慢所有其他标签页的运行速度。或者,如果某个标签页使用了太多内存,则会导致整个浏览器崩溃。

现在的浏览器更加复杂,会尝试将不同的源分隔到不同的进程中。具体工作原理因浏览器而异:大多数浏览器的标签页之间存在一定程度的分隔,但单个标签页中的不同 iframe 可能会共享一个进程。由于进程会产生一些内存开销,因此它们会使用启发词语来避免生成过多进程:例如,Firefox 具有可由用户配置的进程限制,而 Chrome 会在桌面设备(内存较充足)和移动设备(内存较少)之间调整其行为。

这些启发词语并不完美。但它们存在一个重要的限制:由于同源政策存在例外情况,允许 https://sub.a.examplehttps://a.example 等子网域相互通信,因此浏览器无法自动将子网域彼此隔离。

这种默认行为称为“以网站为键的代理集群”:即浏览器会根据网页的网站对网页进行分组。新的 Origin-Agent-Cluster 标头会要求浏览器更改给定网页的这一默认行为,将该网页放入以 origin 为键的代理集群中,以便该网页仅与来源完全相同的其他网页进行分组。具体而言,同网站跨源网页将从代理集群中排除。

通过这种选择性分离,浏览器可以为这些新的以源为键的代理集群分配自己的专用资源,这些资源不会与其他来源的资源合并。例如,此类网页可以获得自己的进程,也可以在单独的线程中进行调度。通过向网页添加 Origin-Agent-Cluster 标头,您向浏览器表明该网页会受益于此类专用资源。

不过,为了实现分离并获得这些优势,浏览器需要停用一些旧版功能。

使用来源键的网页无法执行的操作

当您的页面位于以源为键的代理集群中时,您将放弃一些与之前可用的同网站跨源页面通信的能力。具体而言:

  • 您无法再设置 document.domain。这是一项旧版功能,通常允许同网站跨源网页同步访问彼此的 DOM,但在以源为键的代理集群中,该功能处于停用状态。

  • 您无法再通过 postMessage()WebAssembly.Module 对象发送到其他同一网站跨源网页。

  • (仅限 Chrome)您无法再向其他同网站跨源网页发送 SharedArrayBufferWebAssembly.Memory 对象。

何时使用以源为键的代理集群

最能从 Origin-Agent-Cluster 标头中受益的来源是:

  • 尽可能使用自己的专用资源以实现最佳效果。例如,性能密集型游戏、视频会议网站或多媒体创作应用。

  • 包含不同源但同一网站的资源密集型 iframe。例如,如果 https://mail.example.com 嵌入了 https://chat.example.com iframe,则使用来源键值对 https://mail.example.com/ 可确保聊天团队编写的代码不会意外干扰邮件团队编写的代码,并可向浏览器提示为它们分配单独的进程以便独立调度,从而降低它们对彼此性能的影响。

  • 预计会嵌入到不同来源的同一网站页面上,但自身资源占用较高。例如,如果 https://customerservicewidget.example.com 预计要使用大量资源进行视频聊天,并且将嵌入到 https://*.example.com 中的各种来源,则维护该 widget 的团队可以使用 Origin-Agent-Cluster 标头,以尝试减少其对嵌入程序的性能影响。

此外,您还需要确保您可以停用上述很少使用的跨源通信功能,并且您的网站使用 HTTPS

但归根结底,这些只是指南。最终,最好通过衡量来确定源键代理集群是否有助于您的网站。具体而言,您需要衡量 Web Vitals 指标,以及可能的内存用量,以了解来源键值对的影响。(内存用量尤其值得注意,因为增加使用的进程数量可能会导致每个进程的内存开销增加。)您不应仅仅推出来源键值,然后祈祷一切顺利。

这与跨源隔离有何关系?

通过 Origin-Agent-Cluster 标头为代理集群设置源键与通过 Cross-Origin-Opener-PolicyCross-Origin-Embedder-Policy 标头进行跨源隔离相关,但两者是相互独立的。

任何使自己实现跨源隔离的网站也会停用与使用 Origin-Agent-Cluster 标头时相同的同一网站跨源通信功能。不过,除了跨域隔离之外,Origin-Agent-Cluster 标头仍然有用,可以作为额外的提示来提醒浏览器修改其资源分配启发法。因此,即使在已实现跨源隔离的网页上,您仍应考虑应用 Origin-Agent-Cluster 标头并衡量结果。

如何使用 Origin-Agent-Cluster 标头

如需使用 Origin-Agent-Cluster 标头,请将您的 Web 服务器配置为发送以下 HTTP 响应标头:

Origin-Agent-Cluster: ?1

?1 的值是布尔值 true结构化标头语法。

请务必在源站的所有响应(而不仅仅是某些网页)中发送此标头。否则,您可能会得到不一致的结果,浏览器会“记住”看到来源键值请求,因此即使在未请求来源键值的网页上也会使用来源键值。或者相反:如果用户访问的第一个网页没有标头,则浏览器会记住您的来源不希望使用来源键,并会忽略后续网页上的标头。

为什么浏览器无法始终遵循标头?

之所以有此“内存”,是为了确保来源的键值一致。如果某个源站上的某些网页使用了源站键,而其他网页未使用,那么您可能会有两个同源网页被放入不同的代理集群,因此无法相互通信。这对于 Web 开发者和浏览器内部都是很奇怪的。因此,如果该标头与给定来源之前看到的标头不一致,Origin-Agent-Cluster 的规范会忽略该标头。在 Chrome 中,这会导致控制台警告。

此一致性的作用域限定为浏览上下文组,即一组可以通过 window.openerframes[0]window.parent 等机制相互访问的标签页、窗口或 iframe。这意味着,一旦来源的源键或网站键控得以确定(由浏览器查看或看不到标头),更改它需要打开一个全新的标签页,且不能以任何方式连接到旧标签页。

这些详细信息对于测试 Origin-Agent-Cluster 标头可能很重要。首次将其添加到您的网站时,仅重新加载页面是不够的;您需要关闭标签页,然后打开一个新标签页。

如需检查是否应用了 Origin-Agent-Cluster 标头,请使用 JavaScript window.originAgentCluster 属性。如果标头(或其他机制,例如跨源隔离)导致了源键控,则为 true;如果未导致源键控,则为 false;在未实现 Origin-Agent-Cluster 标头的浏览器中,则为 undefined。将这些数据记录到您的分析平台可以提供有价值的检查信息,以便您检查服务器是否配置正确。

最后,请注意,Origin-Agent-Cluster 标头仅适用于安全情境,即 HTTPS 网页或 http://localhost。非 localhost HTTP 页面支持以源为键的代理集群。

来源键值对不是一项安全功能

虽然使用以源为键的代理集群可以将您的源与来自同一网站的跨源网页的同步访问隔离,但它不会提供 Cross-Origin-Resource-PolicyCross-Origin-Opener-Policy 等安全相关标头的保护。具体而言,它无法可靠地防范 Spectre 等旁道攻击。

这可能有点令人惊讶,因为源键有时可能会导致您的源拥有自己的进程,而单独的进程是防范旁路攻击的重要防御措施。不过请注意,Origin-Agent-Cluster 标头在这方面只是一个提示。浏览器无义务为您的来源提供单独的进程,并且可能出于各种原因而不会这样做:

  • 浏览器可能未实现执行此操作的技术。例如,目前 Safari 和 Firefox 可以将单独的标签页放入自己的进程中,但对于 iframe,还不能这样做。

  • 浏览器可能会认为不值得为单独的进程付出开销。例如,在低内存 Android 设备上或 Android WebView 中,Chrome 会尽可能少使用进程。

  • 浏览器可能想要遵循 Origin-Agent-Cluster 标头指示的请求,但它可以使用与进程不同的隔离技术来实现这一点。例如,Chrome 正在探索使用线程(而非进程)实现此类性能隔离。

  • 用户或在其他网站上运行的代码可能已转到您源站上具有网站键的网页,导致一致性保证生效,并完全忽略 Origin-Agent-Cluster 标头。

因此,请务必不要将以源为键的代理集群视为安全功能。而是通过提示您的来源会受益于专用资源(并且您愿意为此放弃某些功能),帮助浏览器确定资源分配的优先级。

反馈

如果您正在使用或考虑使用 Origin-Agent-Cluster 标头,Chrome 团队非常期待收到您的反馈。您的关注和支持有助于我们确定功能的优先级,并向其他浏览器供应商展示这些功能的重要性。向 @ChromiumDev 发推文,让 Chrome DevRel 团队了解您的想法和体验。

如果您对规范或功能运作方式的详细信息有其他疑问,可以前往 HTML 标准 GitHub 代码库提交问题。如果您在 Chrome 实现方面遇到任何问题,可以前往 new.crbug.com 提交 bug,并将“组件”字段设置为 Internals>Sandbox>SiteIsolation

了解详情

如需详细了解基于来源的代理集群,您可以访问以下链接: