无需共享跨网站数据,即可安全地将内容嵌入网页。
实现状态
本文档简要介绍了一个新的 HTML 元素:<fencedframe>
。
- 围栏框架提案现已正式发布。
- Chrome 平台状态
建议 | 状态 |
---|---|
有关 urn 到配置的 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 中推出 |
引入 reservation.top_navigation_start/commit
GitHub 问题、GitHub 问题 |
将于 2024 年第 1 季度在 Chrome 中推出 |
在 3PCD 之前,请勿停用 ReportEvent 中的 Cookie 设置
GitHub 问题 |
将于 2024 年第 1 季度在 Chrome 中推出 |
添加对跨源子框架中的自动信标的支持
GitHub 问题 |
将于 2024 年第 1 季度在 Chrome 中推出 |
为什么我们需要围栏框架?
围栏框架 (<fencedframe>
) 是嵌入式内容的 HTML 元素,与 iframe 类似。与 iframe 不同,围栏框架会限制与其嵌入上下文的通信,以允许框架访问跨网站数据,而无需与嵌入上下文共享数据。某些 Privacy Sandbox API 可能需要特定文档才能在围栏框架内呈现。
同样,嵌入上下文中的任何第一方数据都不能与围栏帧共享。
例如,假设 news.example
(嵌入上下文)将 shoes.example
中的广告嵌入到围栏框架中。news.example
不能外泄 shoes.example
广告中的数据,shoes.example
也不能通过 news.example
获知第一方数据。
使用存储分区来加强跨网站隐私保护
在浏览网页时,您可能在一个网站上查看过商品,然后又在另一个网站的广告中看到这些商品。
如今,这种广告技术主要是通过使用第三方 Cookie 跨网站共享信息的跟踪技术实现的。这项技术是 Chrome 承诺逐步淘汰的技术,用更可保护隐私的变体取而代之。
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 支持以保护隐私的方式根据用户兴趣投放广告。
- 共享存储空间允许在安全环境中访问未分区的跨站数据。
我们来考虑一下如何将围栏框架与 Protected Audience API 配合使用。借助 Protected Audience API,您可以在广告客户网站上的兴趣群体中记录用户的兴趣,以及用户可能感兴趣的广告。然后,在另一个网站(称为“发布商”)上,系统将对在相关兴趣群体中注册的广告进行竞价,胜出的广告将展示在围栏框架中。
如果发布商在 iframe 中展示胜出的广告,并且脚本可以读取 iframe 的 src
属性,发布商就可以通过该广告的网址推断出访问者的兴趣信息。这并不保护隐私。
使用围栏框架时,发布商可以展示与访问者兴趣相符的广告,但只有框架中的广告客户知道 src
和兴趣群体。发布商无法访问这些信息。
围栏框架的工作原理是什么?
围栏框架使用 FencedFrameConfig
对象进行导航。此对象可通过 Protected Audience API 竞价或共享存储空间的网址选择操作返回。然后,将配置对象设置为围栏框架元素的 config
属性。这与为 src
属性分配了网址或不透明 URN 的 iframe 不同。FencedFrameConfig
对象具有只读的 url
属性;不过,由于当前用例需要隐藏内部资源的实际网址,因此该属性在读取时会返回字符串 opaque
。
围栏框架无法使用 postMessage
与其嵌入器进行通信。不过,围栏框架可以将 postMessage
与围栏框架内的 iframe 一起使用。
围栏框架将通过其他方式与发布商隔离开来。例如,发布商无权访问围栏框架内的 DOM,而围栏框架无法访问发布商的 DOM。此外,name
等属性在围栏框架中不可用。
围栏框架的行为类似于顶级浏览上下文(例如浏览器标签页)。虽然某些用例(例如 opaque-ads
)中的围栏框架可以包含跨网站数据(例如 Protected Audience API 兴趣群体),但该框架无法访问未分区的存储空间或 Cookie。opaque-ads
围栏帧可以访问基于 Nonce 的唯一 Cookie 和存储分区。
如需了解围栏框架的特性,请参阅说明文档。
围栏框架与 iframe 相比有何不同?
现在,您已经知道了哪些围栏框架能用,哪些不可以,不妨与现有 iframe 功能进行比较。
特征 | iframe |
fencedframe |
---|---|---|
嵌入内容 | 是 | 是 |
嵌入的内容可以访问嵌入上下文 DOM | 是 | 否 |
嵌入上下文可以访问嵌入的内容 DOM | 是 | 否 |
可观察属性,例如 name |
是 | 否 |
网址 (http://example.com ) |
是 | 是(具体取决于用例) |
由浏览器管理的不透明来源 (urn:uuid ) |
否 | 是 |
访问跨网站数据 | 否 | 是(具体取决于用例) |
为保护隐私,围栏框架支持的对外通信选项较少。
围栏框架会取代 iframe 吗?
归根结底,围栏框架不会取代 iframe,您也无需使用它们。 当来自不同顶级分区的数据需要在同一页面上显示时,围栏框架是一种更注重隐私保护的框架。
同网站 iframe(有时称为易用 iframe)被视为可信内容。
使用围栏框架
围栏框架将与其他 Privacy Sandbox API 搭配使用,在一个页面中显示来自不同存储分区的文档。目前正在讨论潜在的 API。
此组合目前的候选对象包括:
- 在 TURTLEDOVE API 系列(这是 Protected Audience API 的基础)中,围栏框架可以与共享存储空间的转化量提升情况衡量协同工作。
- 另一种方法是允许围栏框架处于只读状态或访问未分区存储空间。
如需了解详情,请参阅围栏框架用例说明文档。
示例
如需获取围栏框架 config
对象,您必须将 resolveToConfig: true
传递给 Protected Audience API 的 runAdAuction()
调用或共享存储空间的 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; }
标头
浏览器将为围栏框架和嵌入在围栏框架中的 iframe 发出的请求设置 Sec-Fetch-Dest: fencedframe
。
Sec-Fetch-Dest: fencedframe
服务器必须为要在围栏框架中加载的文档设置 Supports-Loading-Mode: fenced-frame
响应标头。围栏框架内的所有 iframe 也必须存在标头。
Supports-Loading-Mode: fenced-frame
共享存储空间上下文
您可能希望使用不公开汇总功能来报告与来自嵌入器的上下文数据相关联的围栏框架中的事件级数据。通过使用 fencedFrameConfig.setSharedStorageContext()
方法,您可以将一些上下文数据(例如事件 ID)从嵌入器传递到由 Protected Audience API 启动的共享存储 Worklet。
在以下示例中,我们会将嵌入器页面上可用的一些数据存储在共享存储空间中,而围栏框架中可用的一些数据存储在共享存储空间中。在嵌入器页面中,将模拟事件 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);
如需详细了解嵌入器在围栏框架配置对象中的上下文,请参阅说明。
试用围栏框架
使用 Chrome 标志启用位于 chrome://flags/#enable-fenced-frames
的 Fenced Frame API。
对话框中有多个选项。我们强烈建议您选择*启用*,以便 Chrome 在有新架构可用时自动更新。
其他选项 Enabled with ShadowDOM 和 Enabled with multiple page framework 提供了仅与浏览器工程师相关的不同实现策略。目前,Enable 与 Enabled with ShadowDOM 的工作方式相同。将来,启用将映射到启用多页面架构。
功能检测
如需确定是否定义了围栏帧,请执行以下操作:
if (window.HTMLFencedFrameElement) {
// The fenced frame element is defined
}
如需确定围栏框架配置是否可用,请执行以下操作:
js
if (window.FencedFrameConfig && frameConfig instanceof FencedFrameConfig) {
// The fenced frame config is available
}
浏览器支持
<fencedframe>
元素仍处于实验模式,因此目前 Chrome 97 及更高版本均支持该元素。目前,其他浏览器不支持它。
互动和分享反馈
围栏框架目前正在积极讨论中,将来可能会发生变化。如果您在试用此 API 时有反馈意见,我们非常期待。
- GitHub:阅读说明文档、提出问题和关注讨论。
- 开发者支持:在 Privacy Sandbox 开发者支持代码库中提问并加入讨论。