安全地将内容嵌入网页,而不会共享跨网站数据。
实现状态
本文档概述了一个新的 HTML 元素:<fencedframe>。
| 提案 | 状态 |
|---|---|
| 将 urn 更改为 config 的 Web API 变更 说明 |
将于 2023 年第 1 季度在 Chrome 中推出。 |
| 广告报告 (FFAR) 的围栏框中的广告素材宏 GitHub 问题 |
将于 2023 年第 3 季度在 Chrome 中推出。 |
| 一次发送自动信标 GitHub 问题 |
将于 2023 年第 3 季度在 Chrome 中推出。 |
| 可序列化的围栏帧配置 GitHub 问题 |
将于 2023 年第 3 季度在 Chrome 中推出。 |
| 针对 Protected Audience 广告尺寸宏的其他格式选项 GitHub 问题 |
2023 年第 4 季度在 Chrome 中推出。 |
| 自动向所有已注册网址发送信标 GitHub 问题 | GitHub 问题 |
2023 年第 4 季度在 Chrome 中推出。 |
| 启用从 Urn iFrame 和广告组件框架退出广告兴趣群组的功能
GitHub 问题 |
2024 年第 1 季度在 Chrome 中推出 |
| 引入了 reserved.top_navigation_start/commit
GitHub 问题、GitHub 问题 |
2024 年第 1 季度在 Chrome 中推出 |
| 在 3PCD 之前,请勿在 ReportEvent 中停用 Cookie 设置
GitHub 问题 |
2024 年第 1 季度在 Chrome 中推出 |
| 添加了对跨源子帧中的自动信标的支持
GitHub 问题 |
2024 年第 1 季度在 Chrome 中推出 |
允许跨源子帧发送 reportEvent() 信标
GitHub 问题 |
2024 年第 2 季度在 Chrome 中推出 |
信标中的 Referer 标头
GitHub 问题 |
2025 年第 1 季度在 Chrome 中推出 |
| 自动信标跨源数据支持
GitHub 问题 |
预计于 2025 年第 2 季度在 Chrome 中推出 |
为什么需要围栏框架?
围栏框架 (<fencedframe>) 是一种用于嵌入内容的 HTML 元素,类似于 iframe。与 iframe 不同,围栏框架会限制与嵌入上下文的通信,以允许框架访问跨网站数据,而不会与嵌入上下文共享这些数据。某些 Privacy Sandbox API 可能需要选择在 Fenced Frame 中呈现的文档。
同样,嵌入上下文中的任何第一方数据都无法与围栏框架共享。
例如,如果 news.example(嵌入上下文)在围栏框架中嵌入来自 shoes.example 的广告,则 news.example 无法从 shoes.example 广告中窃取数据,而 shoes.example 也无法从 news.example 中了解第一方数据。
通过存储分区增强跨网站隐私保护
在浏览网页时,您可能在一个网站上看过某些商品,然后又在完全不同的网站上的广告中看到这些商品。
如今,这种广告技术主要通过跟踪技术来实现,该技术使用第三方 Cookie 在网站之间共享信息。
Chrome 正在开发存储空间分区功能,该功能可按网站分隔浏览器存储空间。如果不进行分区,如果 shoes.example 的 iframe 嵌入到 news.example 中,并且该 iframe 将值存储到存储空间中,则可以从 shoes.example 网站读取该值。存储空间分区后,跨网站 iframe 将不再共享存储空间,因此 shoes.example 将无法访问 iframe 存储的信息。如果 iframe 是从 *.shoes.example 提供并嵌入到 *.shoes.example 中,则浏览器存储空间将共享,因为它们被视为同网站。
存储空间分区将应用于标准存储 API,包括 LocalStorage、IndexedDB 和 Cookie。在分区世界中,第一方存储空间中的信息泄露将大幅减少。
使用跨网站数据
围栏框架是一项 Privacy Sandbox 功能,建议顶级网站对数据进行分区。许多 Privacy Sandbox 提案和 API 旨在满足跨网站用例,而无需使用第三方 Cookie 或其他跟踪机制。例如:
- Protected Audience API 可让广告客户以注重隐私保护的方式投放基于兴趣的广告。
- Shared Storage 允许在安全的环境中访问未分区的跨网站数据。
隔离框架旨在与 Protected Audience API 搭配使用。借助 Protected Audience API,用户的兴趣会以兴趣群体的形式在广告客户的网站上注册,同时注册的还有用户可能感兴趣的广告。然后,在另一个网站(称为“发布商”)上,系统会对相关兴趣组中注册的广告进行竞价,并在受限框架中展示胜出的广告。
如果发布商在 iframe 中展示胜出的广告,并且脚本可以读取 iframe 的 src 属性,则发布商可以从该广告的网址推断出访问者的兴趣信息。这无法保护隐私。
借助围栏框架,发布商可以展示符合访问者兴趣的广告,但 src 和兴趣群组仅对框架中的广告客户可见。发布者无法访问此信息。
围栏框架的工作原理
围栏框架使用 FencedFrameConfig 对象进行导航。此对象可从 Protected Audience API 竞价或 Shared Storage 的网址选择操作返回。然后,将配置对象设置为围栏框架元素的 config 属性。这与将网址或不透明 URN 分配给 src 属性的 iframe 不同。FencedFrameConfig 对象具有只读的 url 属性;不过,由于当前使用情形需要隐藏内部资源的实际网址,因此此属性在读取时会返回字符串 opaque。
围栏框架无法使用 postMessage 与其嵌入者通信。不过,围栏框架可以在围栏框架内使用 postMessage 和 iframe。
围栏框架还会以其他方式与发布商隔离。例如,发布商无法访问围栏框架内的 DOM,而围栏框架也无法访问发布商的 DOM。此外,围栏框架中不提供 name 等属性(可将其设置为任意值并由发布商观察)。
围栏框架的行为方式与顶级浏览上下文(例如浏览器标签页)类似。虽然在某些使用情形(例如基于兴趣的重定向广告)中,围栏框架可以包含跨网站数据(例如 Protected Audience API 兴趣群体),但该框架无法访问未分区的存储空间或 Cookie。围栏框架可以访问基于随机数的唯一 Cookie 和存储分区。
有关围栏框架的特征,请参阅说明文档了解更多详情。
受限框架与 iframe 相比如何?
现在,您已经了解围栏帧可以做什么和不可以做什么,接下来不妨将其与现有的 iframe 功能进行比较。
| 功能 | iframe |
fencedframe |
|---|---|---|
| 嵌入内容 | 是 | 是 |
| 嵌入内容可以访问嵌入上下文 DOM | 是 | 否 |
| 嵌入上下文可以访问嵌入内容 DOM | 是 | 否 |
可观测的属性,例如 name |
是 | 否 |
网址 (http://example.com) |
是 | 是(取决于使用场景) |
浏览器管理的不透明来源 (urn:uuid) |
否 | 有(取决于使用场景) |
| 访问跨网站数据 | 否 | 有(取决于使用场景) |
为了保护隐私,围栏框架支持的外部通信选项较少。
围栏框架会取代 iframe 吗?
最终,围栏框架不会取代 iframe,您也不必使用它们。 围栏框架是一种更私密的框架,适用于需要在同一网页上显示来自不同顶级分区的场景。
同源 iframe(有时称为友好 iframe)被视为可信内容。
使用 Fenced Frames
围栏框架将与其他 Privacy Sandbox API 结合使用,以在单个网页中显示来自不同存储分区的文档。我们正在讨论潜在的 API。
目前,此组合的候选对象包括:
- 在 TURTLEDOVE API 系列(Protected Audience API 的基础)中,围栏框架可使用 Shared Storage 来实现转化提升效果衡量。
- 另一种方法是允许围栏框架为只读或访问未分区的存储空间。
如需了解详情,请参阅围栏框架使用场景说明。
示例
如需获取 FencedFrame config 对象,您必须将 resolveToConfig: true 传递给 Protected Audience API 的 runAdAuction() 调用或 Shared Storage 的 selectURL() 调用。如果未添加该属性(或将其设置为 false),生成的 promise 将解析为只能在 iframe 中使用的 URN。
const frameConfig = await navigator.runAdAuction({ // ...auction configuration resolveToConfig: true });
const frameConfig = await sharedStorage.selectURL('operation-name', { resolveToConfig: true });
获取配置后,您可以将其分配给围栏框架的 config 属性,以使框架导航到配置所表示的资源。旧版 Chrome 不支持 resolveToConfig 属性,因此您仍必须确认 Promise 是否解析为 FencedFrameConfig,然后才能进行导航:
if (window.FencedFrameConfig && frameConfig instanceof FencedFrameConfig) { const frame = document.createElement('fencedframe'); frame.config = frameConfig; }
如需了解详情,请参阅 Fenced Frame 和 Fenced Frame 配置说明。
标头
浏览器将为从围栏框架和嵌入在围栏框架内的 iframe 发出的请求设置 Sec-Fetch-Dest: fencedframe。
Sec-Fetch-Dest: fencedframe
服务器必须设置 Supports-Loading-Mode: fenced-frame 响应标头,才能在围栏框架中加载文档。对于围栏框架内的任何 iframe,也必须存在此标头。
Supports-Loading-Mode: fenced-frame
共享存储空间上下文
您可能需要使用 Private Aggregation 来报告围栏框架中的事件级数据,这些数据与嵌入器中的上下文数据相关联。通过使用 fencedFrameConfig.setSharedStorageContext() 方法,您可以将一些上下文数据(例如事件 ID)从嵌入器传递到由 Protected Audience API 启动的共享存储区工作程序。
在以下示例中,我们将嵌框网页上的一些数据和围栏框架中的一些数据存储在共享存储空间中。在嵌入器网页中,模拟事件 ID 设置为共享存储空间上下文。从围栏框架中,传入框架事件数据。
在嵌入器页面中,您可以将上下文数据设置为共享存储上下文:
const frameConfig = await navigator.runAdAuction({ resolveToConfig: true });
// Data from the embedder that you want to pass to the shared storage worklet
frameConfig.setSharedStorageContext('some-event-id');
const frame = document.createElement('fencedframe');
frame.config = frameConfig;
在围栏框架中,您可以将框架中的事件级数据传递到共享存储空间 worklet(与上述嵌入器中的上下文数据无关):
const frameData = {
// Data available only inside the fenced frame
}
await window.sharedStorage.worklet.addModule('reporting-worklet.js');
await window.sharedStorage.run('send-report', {
data: {
frameData
},
});
您可以从 sharedStorage.context 读取嵌入者的上下文信息,从 data 对象读取框架的事件级数据,然后通过私密聚合报告这些信息:
class ReportingOperation {
convertEventIdToBucket(eventId) { ... }
convertEventPayloadToValue(info) { ... }
async run(data) {
// Data from the embedder
const eventId = sharedStorage.context;
// Data from the fenced frame
const eventPayload = data.frameData;
privateAggregation.contributeToHistogram({
bucket: convertEventIdToBucket(eventId),
value: convertEventPayloadToValue(eventPayload)
});
}
}
register('send-report', ReportingOperation);
如需详细了解围栏框架配置对象中的嵌嵌器的上下文,请参阅说明文档。
试用 fenced frame
使用 Chrome 标志在 chrome://flags/#enable-fenced-frames 启用 Fenced Frame API。
对话框中有多个选项。我们强烈建议您选择*启用*,这样 Chrome 就能在有新架构可用时自动更新到该架构。
其他选项(启用 ShadowDOM 和启用多页面架构)提供了不同的实现策略,这些策略仅与浏览器工程师相关。目前,启用 的工作方式与 启用(使用 ShadowDOM)相同。未来,启用将映射到启用多页面架构。
功能检测
如需确定是否定义了围栏框架,请执行以下操作:
if (window.HTMLFencedFrameElement) {
// The fenced frame element is defined
}
如需确定围栏框架配置是否可用,请执行以下操作:
if (window.FencedFrameConfig && frameConfig instanceof FencedFrameConfig) {
// The fenced frame config is available
}
浏览器支持
互动和分享反馈
围栏框架目前正在积极讨论中,将来可能会发生变化。如果您试用了此 API 并有反馈意见,欢迎随时告诉我们。