围栏框架 API

实验性: 这是一项实验性技术
在将其用于生产之前,请仔细检查浏览器兼容性表格

围栏框架 API(Fenced Frame API)提供了用于控制嵌入在 <fencedframe> 元素中的内容的功能。

概念和用法

Web 上隐私安全问题的一个主要来源是嵌入在 <iframe> 元素中的内容。历史上,<iframe> 被用于设置第三方 cookie,这些 cookie 可用于跨站点共享信息和追踪用户。此外,嵌入在 <iframe> 中的内容可以与其嵌入文档进行通信(例如,使用 Window.postMessage())。

嵌入文档还可以使用脚本从 <iframe> 中读取各种形式的信息,例如,通过读取 src 属性中的嵌入 URL,你可能会获取到重要的跟踪/指纹数据,特别是当 URL 包含 URL 参数时。<iframe> 还可以访问嵌入上下文的 DOM,反之亦然。

大多数现代浏览器都在研究分区存储机制,以便 cookie 数据不再用于跟踪(有关示例请参见具有独立分区状态的 Cookie(CHIPS)Firefox 状态分区)。

<fencedframe> 元素旨在解决这个问题的另一方面——它们在形式和功能上与 <iframe> 相似,但有以下不同:

  • <fencedframe> 内容与嵌入网站之间无法共享通信。
  • <fencedframe> 可以访问跨站数据,但仅限于在非常特定的受控情况下进行,以保护用户隐私。
  • <fencedframe> 不能通过常规脚本进行自由操作或访问其数据(例如读取或设置源 URL)。<fencedframe> 内容只能通过特定 API 嵌入。
  • <fencedframe> 无法访问嵌入上下文的 DOM,嵌入上下文也无法访问 <fencedframe> 的 DOM。

有关围栏框架的通信模型的更多信息,请阅读与嵌入框架的通信指南。

用例

<fencedframe> 被其他 API 用于嵌入不同类型的跨站内容或收集数据,以隐私保护的方式满足不同的使用场景。这些功能以前大多依赖于第三方 cookie 或其他对隐私不利的机制。

  • 共享存储 API 在安全的环境中提供对未分区跨站数据的访问,并在 <fencedframe> 中计算或显示结果。例如:
    • 广告商可以衡量广告的覆盖范围,或者根据用户在其他网站上已经看到的广告来投放后续广告。
    • 开发者可以进行 A/B 测试,根据用户被分配到的组或每个变体已被多少用户查看,来向用户展示不同的内容。
    • 企业可以根据用户在其他网站上的行为来定制用户体验。例如,如果用户已经购买了会员资格,那么在其他网站上就不需要再向他们展示会员注册广告。
  • 受保护的受众 API 允许开发者实现基于兴趣组的广告投放,包括再营销和自定义受众使用场景。它可以评估多个广告位的出价,并在 <fencedframe> 中显示获胜的广告。
  • 隐私聚合 API 可以从 <fencedframe>(来源于共享存储空间或受保护的受众 API)中收集数据,并创建聚合报告。

<fencedframe> 的工作原理

如上所述,你不能通过常规脚本直接控制嵌入在 <fencedframe> 中的内容。

要设置将在 <fencedframe> 中显示的内容,使用 API(如受保护的受众共享存储)生成一个 FencedFrameConfig 对象,然后通过 Javascript 将该对象设置为 <fencedframe>HTMLFencedFrameElement.config 属性

以下示例从受保护的受众 API 的广告拍卖中获取一个 FencedFrameConfig,然后使用它在 <fencedframe> 中显示获胜的广告:

js
const frameConfig = await navigator.runAdAuction({
  // 拍卖配置
  resolveToConfig: true,
});

const frame = document.createElement("fencedframe");
frame.config = frameConfig;

在调用 runAdAuction() 时,必须传入 resolveToConfig: true 以获得 FencedFrameConfig 对象。如果 resolveToConfig 设置为 false,则所得的 Promise 将兑现为一个不透明 URN(例如:urn:uuid:c36973b5-e5d9-de59-e4c4-364f137b3c7a),该 URN 只能在 <iframe> 中使用。

无论哪种方式,浏览器都会存储一个包含要嵌入内容的目标位置的 URL,该 URL 与不透明 URN 或 FencedFrameConfig 的内部 url 属性相对应。在嵌入上下文中运行的 JavaScript 无法读取 UR 值。

备注:<iframe> 中支持不透明 URN,以便将现有实现轻松迁移到隐私沙盒。这种支持是暂时的,随着采用率的提高,未来将会移除。

备注: FencedFrameConfig 有一个 setSharedStorageContext() 方法,用于将数据从嵌入文档传递到 <fencedframe> 共享存储中。例如,它可以在 Worklet 中通过 <fencedframe> 访问,并用于生成报告。参见共享存储 API 查看更多信息。

Fence 对象上访问围栏框架功能

在嵌入到 <fencedframe> 中的文档内,JavaScript 可以访问 Window.fence 属性,此属性为该文档返回一个 Fence 实例。此对象包含几个与围栏框架 API 功能特别相关的函数。例如,Fence.reportEvent() 提供了一种通过信标向一个或多个指定的 URL 触发报告数据提交的方式,以便报告广告展示和点击情况。

权限策略

只有通过设置在 <fencedframe> 上的权限策略,才能启用专门设计为在其中使用的特定功能;在此上下文中,其他受策略控制的特性不可用。参见围栏框架可用的权限策略查看更多信息。

HTTP 标头

对于从 <fencedframe> 内部发出的任何请求,包括嵌入在 <fencedframe> 内的子 <iframe>,都会设置一个值为 fencedframeSec-Fetch-Dest 标头。

http
Sec-Fetch-Dest: fencedframe

服务器必须为任何打算加载到 <fencedframe> 中或嵌入在 <fencedframe> 内的 <iframe> 中的文档设置一个值为 fenced-frameSupports-Loading-Mode 响应标头。

http
Supports-Loading-Mode: fenced-frame

围栏框架对 HTTP 标头字段的其他影响如下:

  • 用户代理客户端提示在围栏框架中不可用,因为它们依赖于权限策略委托,这可能会被用来泄露数据。
  • 对从封闭框架内部打开的新浏览上下文强制执行严格的 Cross-Origin-Opener-Policy 设置,否则它们可能会被用来向其他源泄露信息。从围栏框架内部打开的任何新窗口都将设置 rel="noopener"Cross-Origin-Opener-Policy: same-origin,以确保 Window.opener 返回 null 并将其置于自己的浏览上下文组中。
  • 添加 Content-Security-Policy: fenced-frame-src 来指定加载到 <fencedframe> 元素中的嵌套浏览上下文的有效来源。
  • 为了缓解隐私问题,Content-Security-Policy: sandbox 自定义设置不能被围栏框架继承。要加载围栏框架,需要指定无 sandbox CSP(这意味着以下值),或者指定以下沙箱值:
    • allow-same-origin
    • allow-forms
    • allow-scripts
    • allow-popups
    • allow-popups-to-escape-sandbox
    • allow-top-navigation-by-user-activation

beforeunloadunload 事件

beforeunloadunload 事件不能在围栏框架上触发,因为它们可以以页面删除时间戳的形式泄露信息。实现旨在消除尽可能多的潜在泄漏。

接口

FencedFrameConfig

表示 <fencedframe> 的导航配置,即该框架中将显示什么内容。FencedFrameConfig 由诸如受保护的受众 API 等来源返回,并设置为 HTMLFencedFrameElement.config 的值。

Fence

包含与围栏框架功能相关的多个函数。仅在嵌入在 <fencedframe> 内的文档中可用。

HTMLFencedFrameElement

在 Javascript 中表示一个 <fencedframe> 元素,并提供配置该元素的属性。

对其他接口的扩展

在给定不透明 URN 或 FencedFrameConfig 的内部 url 属性所对应的映射 URL 中,替换指定的字符串。

Window.fence

返回当前文档上下文的一个 Fence 对象实例。仅在嵌入在 <fencedframe> 内的文档中可用。

注册和本地测试

某些创建 FencedFrameConfig 的 API 特性,如 Navigator.runAdAuction()受保护的受众 API)和 WindowSharedStorage.selectURL()共享存储 API),以及其他特性如 Fence.reportEvent(),要求你将你的网站注册到隐私沙盒注册流程中。如果你不注册,API 调用将失败,并在控制台中显示警告。

备注: 在 Chrome 中,你仍然可以在未注册情况下本地测试你的围栏框架代码。要允许本地测试,请启用以下 Chrome 开发者标志:

chrome://flags/#privacy-sandbox-enrollment-overrides

示例

以下演示均使用了 <fencedframe>

规范

Specification
Fenced Frame
# the-fencedframe-element

浏览器兼容性

BCD tables only load in the browser

参见