相关网站集 (RWS) 是一种 Web 平台机制,可帮助浏览器了解一组网域之间的关系。这样,浏览器就可以做出关键决策来启用某些网站功能(例如是否允许访问跨网站 Cookie),并向用户显示这些信息。
随着 Chrome 弃用第三方 Cookie,其目标是在保护用户隐私的同时,维持网络上的关键用例。例如,许多网站依靠多个网域来提供单一用户体验。组织可能希望为多种用例维护不同的顶级域名,例如特定国家/地区的域名或用于托管图片或视频的服务域名。借助“相关网站集”,网站可以通过特定控件在网域之间共享数据。
什么是“相关网站集”?
概括来讲,相关网站集是指一组网域,其中包含一个“集主要网域”和可能多个“集成员网域”。
在以下示例中,primary
列出了主网域,associatedSites
列出了符合关联子集要求的网域。
{
"primary": "https://primary.com",
"associatedSites": ["https://associate1.com", "https://associate2.com", "https://associate3.com"]
}
规范的“相关网站集”列表是一个公开可见的 JSON 文件格式列表,托管在“相关网站集”GitHub 代码库中,该代码库是所有集的可靠来源。Chrome 会使用此文件来应用其行为。
只有对网域拥有管理控制权的用户才能使用该网域创建集。提交者必须声明每个“集成员”与其“集主键”之间的关系。集合成员可以包含一系列不同的网域类型,并且必须属于基于用例的子集。
如果您的应用需要访问同一关联网站集中的网站中的跨网站 Cookie(也称为第三方 Cookie),您可以使用 Storage Access API (SAA) 和 requestStorageAccessFor API 请求访问这些 Cookie。浏览器可能会根据每个网站所属的子集来处理请求。
如需详细了解提交套装的流程和要求,请参阅提交指南。提交的集合将接受各种技术检查,以验证提交内容。
Related Website Set 用例
如果组织需要在不同的顶级网站上使用某种共享身份,Related Website Set 非常适合。
相关网站集的一些用例包括:
- 国家/地区自定义。利用本地化网站,同时依赖共享基础架构(example.co.uk 可能依赖 example.ca 托管的服务)。
- 服务网域集成。利用用户从未直接与之互动,但在同一组织的网站上提供服务的服务网域(example-cdn.com)。
- 用户内容分离。出于安全考虑,访问不同网域上的数据,以将用户上传的内容与其他网站内容分隔开来,同时允许沙盒化网域访问身份验证(和其他)Cookie。如果您要投放闲置的用户上传内容,也可以遵循最佳实践,在同一网域上安全地托管这些内容。
- 嵌入的经过身份验证的内容。支持来自各个关联媒体资源的嵌入内容(仅限于在顶级网站上登录的用户访问的视频、文档或资源)。
- 登录。支持跨关联媒体资源登录。FedCM API 也可能适用于某些用例。
- Google Cloud Analytics。在关联的媒体资源中部署分析和衡量用户转化历程,以提升服务质量。
Related Website Set 集成详情
Storage Access API
Storage Access API (SAA) 提供了一种方法,可让嵌入式跨源内容访问通常只能在第一方环境中访问的存储空间。
嵌入式资源可以使用 SAA 方法检查它们当前是否有权访问存储空间,以及向用户代理请求访问权限。
当第三方 Cookie 被屏蔽但相关网站集 (RWS) 处于启用状态时,Chrome 会在 RWS 内上下文中自动授予权限,否则会向用户显示提示。(“RWS 内上下文”是指嵌入网站和顶级网站位于同一 RWS 中的上下文,例如 iframe。)
检查和请求存储空间访问权限
如需检查自己当前是否有权访问存储空间,嵌入式网站可以使用 Document.hasStorageAccess()
方法。
该方法会返回一个 promise,该 promise 会解析为一个布尔值,指示文档是否已获权访问其 Cookie。如果 iframe 与顶级框架具有相同的来源,该 promise 也会返回 true。
如需请求在跨网站环境中访问 Cookie,嵌入的网站可以使用 Document.requestStorageAccess()
(rSA)。
requestStorageAccess()
API 应从 iframe 内调用。该 iframe 必须刚刚收到用户互动(所有浏览器都要求执行此用户手势),但 Chrome 还要求用户在过去 30 天的某个时间点访问过该 iframe 所属的网站,并且专门以顶级文档(而非 iframe)的形式与该网站互动过。
requestStorageAccess()
会返回一个 promise,用于解析是否已授予对存储空间的访问权限。如果因任何原因被拒绝访问,系统会拒绝该 promise,并说明原因。
Chrome 中的 requestStorageAccessFor
Storage Access API 仅允许嵌入式网站从已收到用户互动的 <iframe>
元素中请求访问存储空间。
这给使用需要 Cookie 的跨网站图片或脚本标记的顶级网站采用 Storage Access API 带来了挑战。
为解决此问题,Chrome 实现了一种方法,可让顶级网站使用 Document.requestStorageAccessFor()
(rSAFor) 代表特定来源请求存储空间访问权限。
document.requestStorageAccessFor('https://target.site')
requestStorageAccessFor()
API 应由顶级文档调用。该文档还必须刚刚收到用户互动。但与 requestStorageAccess()
不同,Chrome 不会检查用户是否在过去 30 天内与顶级文档互动过,因为用户已在该网页上。
检查存储空间访问权限
用户授予的权限决定了能否访问某些浏览器功能(例如相机或地理位置)。Permissions API 提供了一种方法来检查访问 API 的权限状态,即权限是已授予、已拒绝还是需要用户进行某种形式的互动(例如点击提示或与页面互动)。
您可以使用 navigator.permissions.query()
查询权限状态。
如需检查当前上下文的存储空间访问权限,您需要传入 'storage-access'
字符串:
navigator.permissions.query({name: 'storage-access'})
如需检查指定来源的存储空间访问权限,您需要传入 'top-level-storage-access'
字符串:
navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'})
请注意,为保护嵌入源的完整性,此方法仅会检查顶级文档使用 document.requestStorageAccessFor
授予的权限。
具体取决于权限能否自动授予或是否需要用户手势,它将返回 prompt
或 granted
。
每帧模型
rSA 授予适用于每个帧。rSA 和 rSAFor 授予被视为单独的权限。
每个新帧都需要单独请求存储空间访问权限,系统会自动授予访问权限。只有第一个请求需要用户手势,由 iframe 发起的任何后续请求(例如导航或子资源)都无需等待用户手势,因为初始请求会为浏览会话授予该权限。
刷新、重新加载或以其他方式重新创建 iframe 都需要再次请求访问权限。
Cookie 要求
Cookie 必须同时指定 SameSite=None
和 Secure
属性,因为 rSA 仅为已标记为在跨网站情境中使用的 Cookie 提供访问权限。
具有 SameSite=Lax
或 SameSite=Strict
属性或不具有 SameSite
属性的 Cookie 仅供第一方使用,无论是否使用 rSA,都绝不会在跨网站上下文中共享。
安全
对于 rSAFor,子资源请求需要在资源上使用跨域资源共享 (CORS) 标头或 crossorigin
属性,以确保明确选择加入。
实现示例
从嵌入的跨源 iframe 请求访问存储空间

requestStorageAccess()
。检查您是否拥有存储空间访问权限
如需检查您是否已拥有存储空间访问权限,请使用 document.hasStorageAccess()
。
如果 promise 解析为 true,您就可以在跨网站上下文中访问存储空间。如果解析为 false,则需要请求存储空间访问权限。
document.hasStorageAccess().then((hasAccess) => {
if (hasAccess) {
// You can access storage in this context
} else {
// You have to request storage access
}
});
请求存储空间访问权限
如果您需要请求存储空间访问权限,请先检查存储空间访问权限 navigator.permissions.query({name: 'storage-access'})
,看看是否需要用户手势,还是可以自动授予。
如果权限为 granted
,您可以调用 document.requestStorageAccess()
,并且无需用户手势即可成功。
如果权限状态为 prompt
,您需要在用户执行手势(例如点击按钮)后发起 document.requestStorageAccess()
调用。
示例:
navigator.permissions.query({name: 'storage-access'}).then(res => {
if (res.state === 'granted') {
// Permission has already been granted
// You can request storage access without any user gesture
rSA();
} else if (res.state === 'prompt') {
// Requesting storage access requires user gesture
// For example, clicking a button
const btn = document.createElement("button");
btn.textContent = "Grant access";
btn.addEventListener('click', () => {
// Request storage access
rSA();
});
document.body.appendChild(btn);
}
});
function rSA() {
if ('requestStorageAccess' in document) {
document.requestStorageAccess().then(
(res) => {
// Use storage access
},
(err) => {
// Handle errors
}
);
}
}
来自框架、导航或子资源的后续请求将自动获得访问跨网站 Cookie 的权限。hasStorageAccess()
返回 true,则系统会在这些请求中发送来自同一相关网站集的跨网站 Cookie,而无需任何额外的 JavaScript 调用。
代表跨源网站请求 Cookie 访问权限的顶级网站

requestStorageAccessFor()
顶级网站可以使用 requestStorageAccessFor()
代表特定来源请求存储空间访问权限。
hasStorageAccess()
仅检查调用它的网站是否具有存储空间访问权限,因此顶级网站可以检查其他来源的权限。
如需了解系统是否会向用户显示提示,或者是否已向指定来源授予存储空间访问权限,请调用 navigator.permissions.query({name: 'top-level-storage-access', requestedOrigin: 'https://target.site'})
。
如果权限为 granted
,您可以调用 document.requestStorageAccessFor('https://target.site')
。它应该会在不使用用户手势的情况下成功。
如果权限为 prompt
,则您需要在用户手势(例如按钮点击)后钩住 document.requestStorageAccessFor('https://target.site')
调用。
示例:
navigator.permissions.query({name:'top-level-storage-access',requestedOrigin: 'https://target.site'}).then(res => {
if (res.state === 'granted') {
// Permission has already been granted
// You can request storage access without any user gesture
rSAFor();
} else if (res.state === 'prompt') {
// Requesting storage access requires user gesture
// For example, clicking a button
const btn = document.createElement("button");
btn.textContent = "Grant access";
btn.addEventListener('click', () => {
// Request storage access
rSAFor();
});
document.body.appendChild(btn);
}
});
function rSAFor() {
if ('requestStorageAccessFor' in document) {
document.requestStorageAccessFor().then(
(res) => {
// Use storage access
},
(err) => {
// Handle errors
}
);
}
}
成功调用 requestStorageAccessFor()
后,如果跨站请求包含 CORS 或 crossorigin 属性,则会包含 Cookie,因此网站可能需要等待一段时间才能触发请求。
请求必须使用 credentials: 'include'
选项,并且资源必须包含 crossorigin="use-credentials"
属性。
function checkCookie() {
fetch('https://related-website-sets.glitch.me/getcookies.json', {
method: 'GET',
credentials: 'include'
})
.then((response) => response.json())
.then((json) => {
// Do something
});
}
如何在本地进行测试
前提条件
如需在本地测试相关网站集,请使用从命令行启动的 Chrome 119 或更高版本,并启用 test-third-party-cookie-phaseout
Chrome flag。
启用 Chrome 标志
如需启用必要的 Chrome 标志,请从地址栏前往 chrome://flags#test-third-party-cookie-phaseout
,然后将标志更改为 Enabled
。更改标志后,请务必重启浏览器。
启动 Chrome 并设置本地相关网站
如需使用本地声明的“相关网站集”启动 Chrome,请创建一个包含集成员网址的 JSON 对象,并将其传递给 --use-related-website-set
。
详细了解如何使用标志运行 Chromium。
--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/
示例
如需在本地启用“相关网站集”,您需要在 chrome://flags
中启用 test-third-party-cookie-phaseout
,并使用包含集成员网址的 JSON 对象从命令行启动 Chrome 并添加 --use-related-website-set
标志。
--use-related-website-set="{\"primary\": \"https://related-website-sets.glitch.me\", \"associatedSites\": [\"https://rws-member-1.glitch.me\"]}" \
https://related-website-sets.glitch.me/
验证您是否有权访问跨网站 Cookie
从要测试的网站调用 API (rSA 或 rSAFor),并验证对跨网站 Cookie 的访问权限。
Related Website Set 提交流程
请按照以下步骤声明网域之间的关系,并指定它们属于哪个子集。
1. 确定您的 RWS
确定相关网域,包括将纳入相关网站集的设置主要网域和设置成员网域。此外,还要确定每个集合成员所属的子集类型。
2. 创建 RWS 提交内容
创建 GitHub 代码库的本地副本(克隆或分支)。在新分支中,对 related_website_sets.JSON 文件进行更改,以反映您的网站集。为确保您的集合具有正确的 JSON 格式和结构,您可以使用 JSON 生成器工具。
3. 确保您的 RWS 符合技术要求
4. 在本地测试 RWS
在创建拉取请求 (PR) 以提交您的集合之前,请在本地测试提交内容,确保其通过所有必要的检查。
5. 提交 RWS
通过向 related_website_sets.JSON 文件(Chrome 托管规范相关网站集列表的位置)创建 PR 来提交相关网站集。(您需要拥有 GitHub 账号才能创建 PR,并且您需要先签署贡献者许可协议 (CLA),然后才能向该列表贡献内容。)
创建 PR 后,系统会完成一系列检查,以确保您已满足第 3 步中的要求,例如确保您已签署 CLA 且 .well-known
文件有效。
如果成功,PR 将指示已通过检查。我们会每周手动将批准的 PR 批量合并到规范的“相关网站集合”列表中一次(美国东部时间周二中午 12 点)。如果任何检查失败,提交者会通过 GitHub 上的 PR 失败通知收到通知。提交者可以修正错误并更新 PR,但请注意:
- 如果提交失败,系统会显示一条错误消息,其中会提供有关提交可能失败的原因的更多信息。(示例)。
- 所有针对套件提交内容的技术检查均在 GitHub 上进行,因此,因技术检查而导致的所有提交失败情况都将在 GitHub 上显示。
企业政策
Chrome 提供了两项政策来满足企业用户的需求:
- 可能无法与“相关网站集”集成的系统可以使用
RelatedWebsiteSetsEnabled
政策在所有 Chrome 企业版实例中停用“相关网站集”功能。 - 某些企业系统具有仅限内部访问的网站(例如 Intranet),其可注册的域名与其“相关网站集”中的域名不同。如果他们需要将这些网站视为其相关网站集的一部分,但又不想公开显示这些网站(因为这些网域可能属于机密信息),则可以使用
RelatedWebsiteSetsOverrides
政策来补充或替换其公开的相关网站集列表。
Chrome 会通过以下两种方式之一解析公共集和企业集的任何交集,具体取决于是否指定了 replacemements
或 additions
。
例如,对于公开集 {primary: A, associated: [B, C]}
:
replacements 集合: |
{primary: C, associated: [D, E]} |
企业集合会吸收常规网站,从而形成新的集合。 | |
生成的集合: | {primary: A, associated: [B]} {primary: C, associated: [D, E]} |
additions 集合: |
{primary: C, associated: [D, E]} |
公开版和企业版集合在一起。 | |
生成的集合: | {primary: C, associated: [A, B, D, E]} |
排查与 Related Website Set 相关的问题
“用户提示”和“用户手势”
“用户提示”和“用户手势”是两码事。对于同一关联网站集中的网站,Chrome 不会向用户显示权限提示,但 Chrome 仍要求用户与网页互动。在授予权限之前,Chrome 需要用户执行用户手势(也称为“用户互动”或“用户激活”)。这是因为,根据Web 平台设计原则,在“相关网站集”上下文(即 requestStorageAccess()
)之外使用 Storage Access API 也需要用户手势。
访问其他网站的 Cookie 或存储空间
“相关网站集”不会合并不同网站的存储空间,而只是让 requestStorageAccess()
调用更简单(无提示)。关联的网站集仅会降低用户使用 Storage Access API 的使用难度,但不会规定在恢复访问权限后要执行的操作。如果 A 和 B 是同一相关网站集中的不同网站,并且 A 嵌入了 B,则 B 可以调用 requestStorageAccess()
并获得对第一方存储空间的访问权限,而无需提示用户。Related Website Set 不会执行任何跨网站通信。例如,设置关联的网站集不会导致系统开始将属于 B 的 Cookie 发送到 A。如果您想共享这些数据,则必须自行共享,例如,从 B iframe 向 A 帧发送 window.postMessage
。
默认情况下,Cookie 访问权限未分区
相关网站集不允许在不调用任何 API 的情况下隐式访问未分区的 Cookie。默认情况下,相关网站集不会在其中提供跨网站 Cookie;相关网站集只会允许集合中的网站跳过 Storage Access API 权限提示。如果 iframe 想要访问其 Cookie,则必须调用 document.requestStorageAccess()
;或者,顶级页面可以调用 document.requestStorageAccessFor()
。
分享反馈
在 GitHub 上提交一组测试用例,并使用 Storage Access API 和 requestStorageAccessFor
API,您可以借此机会分享您在该过程中的体验以及遇到的任何问题。
如需加入有关 Related Website Set 的讨论,请执行以下操作:
- 加入 Related Website Set 公开邮寄名单。
- 在“相关网站集”GitHub 代码库中提出问题并跟进讨论。