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

新的 HTTP 响应标头,用于限制域范围的脚本编写以及从浏览器请求专用资源。

Domenic Denicola
Domenic Denicola

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

浏览器兼容性

目前,仅在 Chrome 88 及更高版本中实现 Origin-Agent-Cluster 标头。它与 Mozilla Firefox 代表密切合作,并已将其标记为值得进行原型设计,并收到了 Safari 使用的浏览器引擎 WebKit 的代表的初步认可

不过,在此期间,您可以立即为所有用户部署 Origin-Agent-Cluster 头文件。不能理解代码的浏览器会将其忽略。此外,由于以源为键的代理集群中的页面实际上可以执行的操作比以网站为键的代理集群(默认选项)更少,因此无需担心互操作性问题。

为什么浏览器无法自动隔离同网站来源

Web 是基于同源政策构建的,这是一项安全功能,可限制文档和脚本与其他来源的资源进行交互的方式。例如,托管在 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

但归根结底,这些只是一些指南。以源为键的代理集群是否对您的网站有帮助,最终取决于衡量结果。具体而言,您需要衡量网页指标以及内存用量,以了解源键控的影响。(内存用量尤为突出,因为增加正在运行的进程数量可能会导致每个进程的内存开销增加。)您不应只是推出源键控功能并寄希望于成果。

这与跨域隔离有何关系?

通过 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 标头,请将您的网络服务器配置为发送以下 HTTP 响应标头:

Origin-Agent-Cluster: ?1

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

请务必针对来自源站的所有响应(而不仅仅是部分网页)发送此标头。否则,您可能会遇到不一致的结果,即浏览器会“记住”看到过源密钥请求,因此即使在未请求该请求的网页上,浏览器也会生成源密钥。反之:如果用户访问的第一个页面没有标头,浏览器会记住您的源不希望以源为键,并会在后续页面上忽略该标头。

为什么浏览器不能始终遵循标头?

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

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

这些详细信息对于测试 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

了解详情

如需详细了解以源为键的代理集群,您可以访问以下链接了解详情: