围栏框架概览

安全地将内容嵌入网页,而不会共享跨网站数据。

实现状态

本文档概述了一个新的 HTML 元素:<fencedframe>

Proposal Status
Web API changes for urn to config
Explainer
Available in Chrome in Q1 2023.
Creative Macros in Fenced Frames for Ads Reporting (FFAR)
GitHub Issue
Available in Chrome in Q3 2023.
Send Automatic Beacons Once
GitHub Issue
Available in Chrome in Q3 2023.
Serializable Fenced Frames Configs
GitHub Issue
Available in Chrome in Q3 2023.
Additional Format Option for Protected Audience Ad Size Macros
GitHub Issue
Available in Chrome in Q4 2023.
Automatic beacons sending to all registered URLs
GitHub Issue | GitHub Issue
Available in Chrome in Q4 2023.
Enable Leaving Ad Interest Groups from Urn iFrames and Ad Component Frames
GitHub issue
Available in Chrome in Q1 2024
Introduce reserved.top_navigation_start/commit
GitHub issue, GitHub issue
Available in Chrome in Q1 2024
Do Not Disable Cookie Setting in ReportEvent until 3PCD
GitHub issue
Available in Chrome in Q1 2024
Add support for automatic beacons in cross-origin subframes
GitHub issue
Available in Chrome in Q1 2024
Allow Cross-Origin Subframes to Send reportEvent() Beacons
GitHub issue
Available in Chrome in Q2 2024
Referer header in beacons
GitHub issue
Available in Chrome in Q1 2025
Automatic beacon cross-origin data support
GitHub issue
Expected in Chrome in Q2 2025

为什么需要围栏框架?

围栏框架 (<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。

目前,此组合的候选对象包括:

如需了解详情,请参阅围栏框架使用场景说明

示例

如需获取 FencedFrame config 对象,您必须将 resolveToConfig: true 传递给 Protected Audience API 的 runAdAuction() 调用或 Shared Storage 的 selectURL() 调用。如果未添加该属性(或将其设置为 false),生成的 promise 将解析为只能在 iframe 中使用的 URN。

从 Protected Audience API 竞价获取受限框架配置
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 FrameFenced 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 实验中,将名为“启用围栏框架元素”的标志设置为“已启用”

对话框中有多个选项。我们强烈建议您选择*启用*,这样 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 并有反馈意见,欢迎随时告诉我们。

了解详情