侧边栏

浏览器同站策略

发布于 | 分类于 前端/前端业务

最近在排查浏览器性能问题的时候,需要了解浏览器对于单个标签页的内存资源分配机制。浏览器的内存分配机制涉及多个层次,包括进程、线程和沙箱环境。

由于我们的页面还存在iframe嵌套的情况,对于iframe是同一个域名还是不同域名,也存在显著的差异。这种差异是出浏览器同源same-origin同站same-site策略影响的,需要深入理解一下同站的概念。

参考

同站的概念

同源

作为前端开发,对于同源策略应该是比较熟悉的,最常见的接口跨域请求、iframe跨域通信等问题。

浏览器的同源策略(Same-Origin Policy),指协议(Protocol)、域名(Host)、端口(Port)三者完全相同,才说明两个资源是同源的。

同源策略用于限制不同源的文档或脚本之间的交互,是浏览器最严格的安全策略。例如:

  • 禁止跨源读取DOM、Cookie、LocalStorage等资源。
  • 禁止跨源发送某些类型的请求(如AJAX)。

同站

**同站策略(Same-Site)**是浏览器用来判断两个网站是否属于同一“站点“的策略,以决定不同网页或资源之间是否可以共享数据(如 Cookie、Storage、Service Workers 等),以及如何实施一些安全策略(比如隔离、权限限制)。

在浏览器安全和隐私策略中,一般使用eTLD+1(effective Top-Level Domain + 1)来划分两个“站点”是否相同,

ETLD+1

参考:有效顶级域 - MDN

eTLD+1 指的是“有效顶级域名(eTLD)+1 个子域名”,用来表示一个“站点”的基本单位。

完整域名eTLDeTLD+1
www.example.comcomexample.com
shop.example.co.ukco.ukexample.co.uk
a.b.c.d.example.comcomexample.com

有效顶级域名(eTLD)并不是简单的最后一个后缀,而是基于公共后缀列表 Public Suffix List (PSL) 来定义的,比如:

  • com, org, net 是常见的顶级域名;
  • co.ukgov.cn 等多级结构也会作为一个整体被当作 eTLD。

同站限制

浏览器使用 eTLD+1 来实现一些“站点级”安全策略,主要包括以下几个方面:

Same-site 策略(SameSite Cookie、SameSite Navigation)

  • 浏览器判断两个请求是否“同站点”(Same Site),就会使用 eTLD+1 比较。
  • 只有 eTLD+1 相同的请求才被认为是同站点,才可以共享某些 Cookie(SameSite=Lax/Strict 控制)。

Storage Partitioning(存储隔离)

  • 现代浏览器(尤其是 Safari、Firefox 和 Chrome 的隐私沙盒)会把 localStorageIndexedDB 等按 eTLD+1 分区隔离,防止跨站跟踪。

Site Isolation(站点隔离)

  • Chrome 的站点隔离功能会基于 eTLD+1 将网页放入不同的进程中,以阻止 Spectre 类攻击窃取其他站点数据。

浏览器同站资源分配

现代 Web 浏览器采用多进程架构,不同来源的页面可以在不同的操作系统进程中运行。这对于性能至关重要,因为这意味着资源密集型页面不会对用户打开的其他页面造成太大影响。

然而,由于某些 DOM API 依赖于同站点、跨域通信,浏览器通常无法在不同的进程中运行同站点、跨域页面。

因此,在多进程架构下,浏览器为每个站点(基于同站规则)分配独立进程,这意味着两个相同域名的标签页可能会共享一个独立进程?这一点跟大部分人理解的一个标签页一个渲染进程是有出入的。

浏览器可能为每个标签页分配独立进程(早期模型),但更多情况下会按同站规则合并进程以节省资源。例如:打开多个 a.example.com 的标签页,它们可能共享同一进程。

场景收益风险
同站标签页共享进程减少内存占用,提升性能一个标签页崩溃可能导致同进程其他标签页崩溃
独立进程分配崩溃隔离、安全性增强(如防Spectre攻击)内存占用更高

简单来说,浏览器的资源分配是浏览器内部的优化策略

  • 如果两个标签页的域名属于同一站点(例如 a.example.comb.example.com),浏览器可能将它们合并到同一进程。
  • 如果两个标签页是完全相同的 URL(例如两个 https://a.example.com/page),浏览器更倾向于共享进程。
  • 如果某个标签页消耗大量内存或 CPU,浏览器可能将其拆分到独立进程,避免影响其他标签页。
  • Chrome 会为**不同站点(Same-Site)**分配独立进程,即使这些站点属于同一浏览器标签页中的不同 iframe。

需要注意的是,上面的策略是一个动态的过程,浏览器会在性能优化安全性之间取得平衡

如果想验证标签页是否共享进程,可以通过Chrome 任务管理器实现:打开 Chrome 的菜单 → 更多工具 → 任务管理器,查看标签页的进程 ID。

  • 同一进程 ID 的标签页共享进程。
  • 不同进程 ID 的标签页独立运行。

强制不同站点

上面提到,对于不同站点而言,浏览器会分配独立的进程,这意味着同一个页面里面包含的iframe,可能对应了两个独立的进程。

由于浏览器为每个进程分配的内存是有上限的,如果项目存在嵌套iframe的场景,而浏览器通过站点策略将iframe和主页面共享了进程,就会导致两个页面公用页面上限,出现一些性能问题。

人浏览器可以为不同站点分配独立的资源来渲染,这可以作为一种性能优化的方案。

最简单的即使将代码部署到两个完全不同的ETLD+1的域名下面,符合不同站点的规范,让浏览器分配独立的进程。

但在大多数场景下,我们只会有一个域名,这种场景下,有没有什么机制可以让两个相同的ETLD+1也走不通站点此类呢?

在这种场景下,可以使用`Origin-Agent-Cluster:这个HTTP响应头来实现(注意该响应头目前还是带实验性质的,参考Origin-Agent-Cluster - MDN

http
Origin-Agent-Cluster: ?1

通过设置Origin-Agent-Cluster标头,页面可以请求浏览器为该来源分配专用资源,这些资源不与任何其他来源共享。

请求浏览器为当前页面分配独立进程(即使同站点)。限制:

  • 仅Chrome支持且非标准
  • 不改变站点定义,仅进程隔离

基于源的代理集群不应被视为一项安全功能:浏览器可能会出于各种原因忽略请求,或者选择以不提供内存保护的方式实现它(例如,使用单独的线程而不是单独的进程)。相反,此功能暗示如果为该源分配专用资源,用户体验将会得到改善。

小结

在前端开发中,对同源策略接触的比较多,而对于同站策略,实际上了解不多,从其功能来看,同站在浏览器安全、资源分配等场景都有作用,了解这些功能还是很有必要的。

你要请我喝一杯奶茶?

版权声明:自由转载-非商用-保持署名和原文链接。

本站文章均为本人原创,参考文章我都会在文中进行声明,也请您转载时附上署名。