1. 引言
本节是非规范性的。
在一个其 cookie 和存储按顶层框架站点进行分区的 Web 中,有些场合——例如由 [Protected-Audience] API 提供的基于兴趣组的广告,或 转化
提升
测量)
——会需要在同一页面中显示来自不同分区的内容。只有当包含来自不同
分区数据的 Document
彼此隔离、虽然在同一页面上以视觉方式重新组合但仍无法通信时,这才能以保护隐私的方式完成。
iframe
元素并不适合这种场景,因为它们与其嵌入者之间提供了许多有意设计的
通信通道。本规范引入了
fencedframe
元素,这是一个用于在页面上嵌入 Document
的新元素,它明确阻止该 Document
与其嵌入者之间的通信。
本规范定义了这个新元素、它与 Web 平台其他部分的集成,包括 § 3 HTML 集成 和 § 4 与其他规范的交互,以及其支持性的
基元
例如 FencedFrameConfig,
它是
fencedframe
的主要输入,用来取代普通
URL
和 "src" 属性。鉴于本规范定义了一个新元素及其与平台其余部分的
集成,因此应主要将其理解为对
[HTML] 的猴子补丁,其最终目标是在具有足够的
跨浏览器支持后合并到该标准中。
2. fencedframe 元素
- 类别:
- 流内容.
- 短语内容.
- 嵌入内容.
- 交互内容.
- 可感知内容.
- 短语内容.
- 可使用此元素的上下文:
- 在预期使用嵌入内容的位置。
- 内容模型:
- 无内容.
- 内容属性:
- 全局属性
width— 水平尺寸height— 垂直尺寸— 要应用到allowfencedframe内容的 权限策略 - 无障碍注意事项:
-
TODO
- DOM 接口:
-
[
Exposed =Window ]interface :HTMLFencedFrameElement HTMLElement { [HTMLConstructor ](); [constructor CEReactions ]attribute FencedFrameConfig ?config ; [CEReactions ]attribute DOMString width ; [CEReactions ]attribute DOMString height ; [SameObject ,PutForwards =value ]readonly attribute DOMTokenList sandbox ; [CEReactions ]attribute DOMString allow ; };
fencedframe
元素表示其围栏可导航体。
fencedframe
元素的后代不表示任何内容。
每个
fencedframe
都有一个 config,它要么是
FencedFrameConfig,
要么是 null。其初始值为 null。
每个
fencedframe
都有一个 fencedframe 沙盒化标志集,它是一个
沙盒化标志集。某一特定时刻 fencedframe 沙盒化标志集中设置了哪些标志
由
fencedframe
元素的
sandbox
属性决定。
-
如果 embedder 是一个
iframe元素,则:设置在 embedder 的 iframe 沙盒化标志集上的标志。 -
如果 embedder 是一个
fencedframe元素,则:设置在 embedder 的 fencedframe 沙盒化标志 集上的标志。
fencedframe
元素 element 被插入到一个
document 中,且该 document 的 浏览上下文为非 null 时,运行以下步骤:
-
令 nested traversable 为为 element 创建新的 嵌套可遍历体的结果。
-
将 nested traversable 的 加载模式设置为 "
fencedframe"。 -
如果 element 具有
sandbox属性,则以该属性的值和 element 的 fencedframe 沙盒化标志 集为参数解析沙盒化指令。
不必像通常进行子
可导航体创建或顶级
可遍历体创建时那样调用 URL
和历史记录更新步骤,但我们仍然需要一种机制来初始化新可导航体中的
History.length。
这是 HTML Standard 中的一个现有问题:https://github.com/whatwg/html/issues/9030。
fencedframe
元素被从 document 中移除时,用户代理必须运行
以下步骤:
-
TODO: 销毁嵌套可遍历体。
-
并行地,给定该
Document的 节点可导航体的 顶级可遍历体,重新计算 所有围栏框架后代的不受信任网络状态。
config IDL 属性的 getter 步骤
是返回
this 的 config。
config
IDL 属性的 setter 步骤如下:
-
令 navigation url or urn 为给定
FencedFrameConfig的 url, 如果 给定FencedFrameConfig的 url 不是 null;否则为给定FencedFrameConfig的 urn。 -
如果 navigation url or urn 是 failure,则返回。
-
令 shared storage context 为给定
FencedFrameConfig的 sharedStorageContext。 -
使用 element 的 节点 document,将 element 的 围栏可导航体导航到 navigation url or urn,其中 historyHandling 设为 "
replace",referrerPolicy 设为 "no-referrer",并使用 shared storage context。注: 有关普通 导航流程中针对
fencedframe的特定 更改,请参见 § 3.8.5 实际导航更改。
allow 属性在指定时,决定当
fencedframe
的
围栏可导航体中某个 Document
的
权限策略被初始化时,将使用的
容器策略。其值必须是一个序列化权限策略。[PERMISSIONS-POLICY]
sandbox 属性在指定时,会对由
fencedframe
承载的任何内容启用一组
额外限制。
其值必须是一个由唯一空格分隔 token 组成的无序集合,
这些 token ASCII 大小写不敏感。允许的值为:
IDL 属性 allow 和
sandbox 必须反映对应的同名内容属性。
sandbox
的
DOMTokenList
所支持的 token,是在
sandbox
属性中定义并受用户代理支持的允许值。
fencedframe
元素:
-
如果 localName 是
sandbox, 则:-
如果 value 是 null,则清空 element 的 fencedframe 沙盒化 标志集。
-
否则,给定 value 和 element 的 fencedframe 沙盒化 标志集,运行解析沙盒化指令。
-
2.1. 尺寸属性
本节详述对 [HTML] 的尺寸
属性章节所作的猴子补丁。该章节将被更新,以便在其自身的 width
和 height 尺寸属性具有与
[HTML] 中定义的一般
width
和
height
尺寸属性相同作者要求的元素列表中,包含
fencedframe。
此外,IDL 属性 width 和
height 必须反映各自的同名内容属性。
2.2. 围栏框架配置映射
每个 可遍历可导航体都有一个 围栏 框架配置 映射,它是一个围栏框架配置映射。
注: 此映射会在导航期间被查阅,并由我们
口语上称为 URN-generating APIs 或 config-generating APIs 的 API 写入,这些 API 生成
urn
uuid 和 围栏框架配置,以用于导航
fencedframe
和
iframe
元素。
例如参见 [Protected-Audience] API 和 [Shared-Storage] 规范。
一个 围栏框架 配置映射具有三个子映射:
- 待定配置映射
- 已完成配置 映射
- 嵌套配置映射
注: 待定配置的目的是让
config-generating APIs 能以不产生计时旁路的方式异步解析配置,也就是说,在任何其耗时
取决于跨站点数据的计算之前,待定配置会以恒定时间量返回给 Web 平台。
由于这项隐私保护依赖于 Web 平台无法辨别待定配置何时完成,因此重要的是所有
可见性以及透明字段的值,在从待定
配置到已完成配置的过程中都不发生变化,因为它们可以通过 FencedFrameConfig
的
getter 被检查。因此,一个被创建并暴露给 Web 平台的 FencedFrameConfig
实际上是不可变的,即使该 config
的 urn 所表示的
围栏框架配置在技术上是“待定”的,并且会在稍后完全
解析完成。
每个围栏框架配置映射都有一个 最大配置 数量,它是实现定义的。最大配置数量可以是 非负数或无穷大。
注: 指定 最大配置数量的行为很重要, 因为其语义可能以隐私敏感的方式与 config-generating APIs 交互。
在高层次上,为了在 围栏框架配置映射中存储一个 围栏框架配置, 配置的创建者必须先存储一个 待定配置,然后将该待定配置变为已完成配置。这些过程如下:
-
令 nestedMapping 为 mapping 的 嵌套配置映射。
-
如果 nestedConfigs 为 null,则返回。
-
对于 nestedConfigs 中的每个 urn → config 执行:
-
设置 nestedMapping[urn] 为 config。
-
将 nestedMapping[urn] 的 is ad component 设为 true。
-
2.3. 围栏框架配置
2.3.1. 引言
本节是非规范性的。
fencedframe
元素的一个关键特性是,Web 平台 API 可以以一种限制其他执行上下文修改或检查此
配置能力的方式来配置框架的行为,这是出于安全和隐私原因。例如,[Protected-Audience] API
会对跨站点数据执行设备端广告竞价,重要的是赢得竞价的广告能够被加载到一个框架中,
而 API 调用方既不知道哪个广告赢得了竞价,也不能操纵该广告加载时的环境。
我们使用“围栏框架配置”这一概念来实现这一点。围栏框架配置是一组字段的
集合,可以被加载到
fencedframe
元素中,并指定
产生的环境。围栏框架配置只能由特定的 Web 平台
API 创建,
不能由脚本构造或修改。它们的字段还包含
“可见性”,用于规定当通过 FencedFrameConfig
接口检查字段时,该字段是否应被“遮蔽”。像
[Protected-Audience] 和 [Shared-Storage] API 这样的 config-generating
APIs
必须为其
围栏框架
配置的所有字段指定值,以确保它们已经考虑了每个字段的隐私影响,尽管它们可以选择将这些值设为 null。
每当一个
fencedframe
导航到一个围栏
框架配置时,它会被实例化为一个新的
围栏框架配置实例,该实例治理
围栏可导航体内部的特定
浏览上下文组。
2.3.2. 用例
渲染通过广告竞价创建的广告:
广告竞价 API 运行一次竞价并确定获胜广告。有关获胜广告的详情必须
对嵌入者隐藏,并且不允许嵌入上下文影响
fencedframe
的环境。
这两种情况都会允许信息跨越围栏框架边界流动,从而可能允许串通方合并跨站点数据并建立用户画像。
为了防止这种情况,广告竞价 API 构造一个
围栏框架
配置,其底层 URL 对
嵌入上下文是不透明的。该围栏框架配置还会被构造为带有关于该框架的
容器尺寸和内容尺寸
必须为何值,以及该框架的权限策略必须为何值的限制,因为这些都可用作指纹识别向量。
显示个性化支付按钮:
一个电商网站嵌入一个
fencedframe,
其中包含一个“立即支付”按钮。该电商网站将用户信用卡信息作为第一方存储保存在浏览器中。
起初,托管在
fencedframe
中的
Document
没有第一方 cookie/存储访问权限,因此信息可以自由流入流出,而不会有信用卡信息与跨站点
数据合并的风险。因此,可以使用
FencedFrameConfig
构造函数直接从 Web 平台构造该围栏框架,而不损害隐私。此时按钮中没有
个性化数据,因为它还不能访问信用卡数据。该 Document
只有在它通过
disableUntrustedNetwork()
关闭所有网络访问后,才能读取该信用卡数据,
这会阻止数据流出围栏框架,并阻止它与跨站点数据合并以建立用户画像。一旦这样做,
按钮便会显示用户信用卡号的最后 4 位,按照其保存在浏览器中、位于该电商平台来源的第一方存储分区中的内容显示。
2.3.3. 围栏框架配置结构体
我们现在建立一些预备类型:
可见性要么是 "opaque",要么是 "transparent"。
- 宽度
-
一个非负整数
- 高度
-
一个非负整数
TODO: 考虑为这些成员使用不同的数值类型。
权限策略行为要么是 "fixed",要么是 "flexible"。
默认围栏框架有效 沙盒化标志是一个 沙盒化标志集,具有以下标志:
围栏框架报告映射是一个映射,
其键
是 FenceReportingDestination,
其值要么是:
注: 此表示方式旨在允许 config-generating APIs 通过异步解析报告目标的值来降低延迟,即使在它们已经构造并返回 围栏框架配置之后,甚至在配置已加载且事件报告已在围栏框架内部生成之后也可以这样做。 当 config-generating API 声明围栏框架报告映射时,它们可以使用一个空 列表将某些目标标记为待定,然后 保留对该映射的引用以供稍后使用。如果围栏框架尝试在某个目标仍处于待定状态时向其 报告事件,它会将该事件存储在此 列表中以供稍后 处理。当 config-generating API 或其回调最终通过其保留的引用完成报告目标时, 它会处理存储在该列表中的所有待定事件。如果该目标永远没有完成,则这些待定事件将永远 不会被发送。
不受信任网络状态要么是 "enabled",
"disabled for this tree",或
"disabled for this tree and fenced subtrees"。
注: Disabled for this tree 不是最终的 网络切断状态。它是一个中间状态,在该状态中,框架树内所有未跨越围栏框架边界的框架 都已撤销其网络访问权限,但至少还有一个子围栏框架树仍具有网络访问权限。在此阶段它不会获得特殊 API 访问权限,因为它获得访问权的任何信息仍可通过具有网络访问权限的子围栏框架被外泄。 一旦所有子围栏框架也都禁用了其不受信任网络,围栏框架的状态就会切换到最终的 disabled for this tree and fenced subtrees 状态。
FenceReportingDestination
destination,一个
源 reporting url declarer origin,一个映射
destination map,其键
是
字符串,且
其值是 url,以及 macro
map,它要么是 null,要么是一个
映射,
其键是字符串,其值是字符串,运行这些
步骤:
-
断言 reporting map[destination] 是一个 列表 (即 destination 的 元数据尚未完成)。
-
令 pending event list 为 reporting map[destination]。
-
设置 reporting map[destination] 为一个具有以下项的结构体:
- 报告 url 声明者源
-
reporting url declarer origin
- 报告 url 映射
-
destination map
- 报告宏映射
-
macro map
-
对于 pending event list 中的每个 pending event 执行:
-
使用 destination map、pending event 的 事件、 pending event 的 请求发起者,以及 pending event 的 发起者 referrer 策略发送 beacon。
-
自动 beacon 事件类型要么是 "reserved.top_navigation_start",
"reserved.top_navigation_commit",
或 "reserved.top_navigation"。
reserved.top_navigation
是
reserved.top_navigation_commit
的早期
命名。
虽然它们
做的是同一件事,
reserved.top_navigation
将来会被
移除,不应在新代码中使用。
- 围栏框架报告元数据 引用
-
对一个围栏框架报告元数据的可变引用 TODO: 以更符合规范风格的方式处理指针/引用
目标 URL 事件是一个 URL。
目标事件要么是 目标枚举事件,要么是 目标 URL 事件,或是 自动 beacon 事件。
-
令 destination url 为空字符串。
-
令 attributionReportingEligibility 为 "
unset"。 -
令 processResponse 为 null。
-
令 useParallelQueue 为 false。
-
如果 event 是目标枚举事件或 自动 beacon 事件,则:
-
令 destination map 为 destination info 的 报告 url 映射。
-
如果 destination map[eventType] 不存在, 返回。
-
将 destination url 设置为 destination map[eventType]。
-
如果 event 的 attributionReportingEnabled 为 true 且 event 的 attributionReportingContextOrigin 是合适的:
-
如果 event 的
eventType匹配某个自动 beacon 事件类型值,则将 attributionReportingEligibility 设置为 "navigation-source"。 -
否则,将 attributionReportingEligibility 设置为 "
event-source"。 -
将 processResponse 设置为给定一个响应 response 的这些步骤:
-
令 fenced 为 true。
-
使用 event 的 attributionReportingContextOrigin、 attributionReportingEligibility、fenced 和 response 运行处理 归因合格响应。
-
-
将 useParallelQueue 设置为 true。
-
-
-
否则:
-
可选地,返回。
注: 这个实现定义的条件旨在 允许用户代理出于多种原因丢弃该 beacon,例如用户选择退出,或 destination url 的站点未 登记。
-
令 request 为一个新的请求,具有以下属性:
- 方法
-
如果 event 是目标枚举事件,则为
, 否则为POST。GET - URL
-
destination url
- 标头列表
- 主体
- 客户端
-
null
- service-workers 模式
-
"all"默认值是
"all",因此从技术上讲我们不必在这里设置任何内容。我们这样做是为了 提醒自己,这里跳过 service workers 可能更合适,类似于某些 其他 beacon。 - 源
-
如果 event 是目标 URL 事件,则为 request initiator,否则为 destination info 的 报告 url 声明者源。
注: 目标 URL 事件的报告目标 由调用
reportEvent()的Document决定, 不同于目标枚举事件或 自动 beacon 事件, 后者的报告 目标是在创建加载此Document的围栏框架 配置的 worklet 中决定的。 我们将源设置为决定报告目标的Document或 worklet 的源,以防止跨站请求伪造。 - referrer
-
request initiator
- referrer 策略
-
initiator referrer policy
- 模式
-
"cors" - 凭据模式
-
"omit" - Attribution Reporting eligibility
-
attributionReportingEligibility
-
Fetch request,其中 processResponse 为 processResponse(如果它不是 null),且 useParallelQueue 为 useParallelQueue。
注: 此算法可以在并行期间调用,也可以在
Document的 主 线程上调用。为了正确处理并行调用,我们在使用可选的 响应处理算法时,会调用 fetch 并将 useParallelQueue 设为 true;否则,即使此 算法在其他实例中并行运行,也无需这样做。
FenceReportingDestination
destination、一个源 request initiator、
一个referrer 策略 initiator referrer policy,以及一个目标事件
event 报告
事件,运行以下步骤:
-
令 metadata 为 reporter 的 围栏框架 报告元数据引用。
-
如果 destination 是
"direct-seller":-
如果 metadata 的 直接卖方 是卖方为 true,则将 destination 设置为
"seller"。 -
否则,将 destination 设置为
"component-seller"。
-
-
如果 event 是一个目标 URL 事件:
-
如果 event 的源不与 metadata 的 允许的 报告源中的任一条目同源:
-
将 metadata 的 尝试 向不允许源进行自定义 url 报告设置为 true。
-
-
如果 metadata 的 尝试 向不允许源进行自定义 url 报告为 true,则返回。
-
-
令 reporting map 为对 metadata 的 围栏框架 报告映射的引用。
-
如果 reporting map[destination] 不存在,返回。
-
如果 reporting map[destination] 是一个列表:
-
断言 reporting map[destination] 是一个 映射(即 destination 的 元数据已经完成)。
-
使用 reporting map[destination]、event、request initiator 和 initiator referrer policy发送 beacon。
- 源
-
一个源
- 要扣减的量
-
一个非负有效浮点数
- 源
-
一个源
- 要扣减的量 引用
-
对一个非负有效浮点数的可变引用 TODO: 以更符合规范风格的方式处理指针/引用
分区 nonce是一个 实现定义的值。
- 映射 url
- 容器尺寸
-
null,或一个尺寸
- 内容尺寸
- 兴趣组描述符
- on navigate 回调
-
null,或一系列步骤
- 有效沙盒化标志
- 有效启用权限
-
- 值
- 可见性
-
一个可见性
注: 当非 null 时,这是一个由受策略控制的特性组成的列表, 此配置的生成器依赖这些特性在导航到此配置的
fencedframe内部被独占启用。具体而言,此列表中的每个特性必须 在导航到此配置时,由该fencedframe的 围栏可导航体的 权限策略的继承策略启用,导航才会成功。 此列表中的特性不是被强制启用,而是用于检查影响上述 继承策略的嵌入者环境是否足够宽松, 能够支持这些必要 特性。如果这些特性中任一特性的继承策略值为 "Disabled",则导航到此配置会失败。任何受策略控制的特性只要不在 此列表中,就不会在导航到此配置的fencedframe中被设为 "Disabled"。
- 围栏框架报告元数据
-
- 值
- 可见性
-
一个可见性
- 外泄预算元数据
- 嵌套配置
- 嵌入者 shared storage 上下文
-
null,或一个字符串
- is ad component
-
一个布尔值,初始值为 false。
注: 当为 true 时,此围栏框架配置 表示一个广告组件。广告组件可用于构造由多个片段组成的广告。参见 Protected Audience explainer。对于广告组件,事件报告的处理方式不同。参见描述此内容的 Fenced Frame Ads Reporting explainer。
- 允许跨源报告
-
一个布尔值,初始值为 false。
2.3.4. 围栏框架配置 实例结构体
- 映射 url
-
一个 URL
- 容器尺寸
-
null,或一个尺寸
- 内容尺寸
-
null,或一个尺寸
- 兴趣组 描述符
-
null,或一个兴趣组描述符
- on navigate 回调
-
null,或一系列步骤
- 有效沙盒化 标志
-
null,或一个沙盒化标志集
- 权限策略 行为
-
一个权限策略行为
- 有效启用 权限
- 围栏框架报告器
-
null,或一个围栏框架报告器
- 外泄 预算元数据引用
-
null,或一个外泄预算元数据 引用
- 嵌套配置
- 分区 nonce
-
一个分区 nonce
- 嵌入者 shared storage 上下文
-
null,或一个字符串
- is ad component
-
一个布尔值
- 不受信任网络 状态
- 网络禁用时 promise
-
一个映射,其键是全局对象,且值是由
Promise组成的列表, 初始为空。注: 这会存储在
disableUntrustedNetwork()期间从各个全局对象创建的各种Promise。 我们将它们存储在此处,以便当fencedframe及其后代围栏框架的网络访问权限被完全 撤销时(即不受信任网络状态 为disabled for this tree and fenced subtrees),可以一次性解析所有这些 promise。 - 允许跨源报告
-
一个布尔值,初始值为 false。
- 映射 url
- 容器尺寸
-
config 的容器尺寸
- 内容尺寸
- 兴趣组 描述符
- on navigate 回调
-
config 的on navigate 回调
- 有效沙盒化 标志
- 权限策略 行为
- 有效启用 权限
- 围栏框架报告器
-
-
如果 config 的围栏框架 报告元数据的值为 null,则设为 null。
-
否则,设置为一个围栏框架报告器,具有 以下 成员:
- 围栏 框架报告元数据引用
-
对 config 的围栏 框架报告元数据的 值的引用
-
- 外泄 预算元数据引用
- 嵌套配置
- 分区 nonce
-
一个随机、唯一的分区 nonce
- 嵌入者 shared storage 上下文
-
config 的嵌入者 shared storage 上下文
- is ad component
-
config 的is ad component
- 允许跨源报告
-
config 的允许跨源报告
- 不受信任网络状态
- 网络禁用时 promise
-
一个空的映射。
每个浏览上下文都有一个 围栏框架配置实例, 它是一个围栏框架配置实例或 null,初始为 null。
此围栏框架配置实例实际上应存在于
浏览上下文组上;不过,在第三方 cookie
被弃用之前,本
规范在
fencedframe
概念的许多方面支持
iframe
元素。这要求
在短期内,一个普通的内容可导航体能够加载
围栏框架
配置,因此能够访问该导航对应的围栏框架配置
实例。
2.3.5.
FencedFrameConfig
接口
fencedframe
元素的一个主要输入是 FencedFrameConfig
接口,它
映射到一个内部的围栏框架配置结构体。
enum {OpaqueProperty }; ["opaque" Exposed =Window ,Serializable ]interface {FencedFrameConfig constructor (USVString );url undefined setSharedStorageContext (DOMString ); };contextString
每个 FencedFrameConfig
都具有:
注: 只有在提供了 urn 时, config 的 url 才为 null。
FencedFrameConfig(url)
构造方法步骤
如下:
-
令 config 为一个新的
FencedFrameConfig对象。 -
返回 config。
FencedFrameConfig
对象是可序列化对象。给定
value、serialized 和 forStorage,它们的序列化步骤为:
-
如果 forStorage 为 true,则抛出一个
DataCloneErrorDOMException。 -
将 serialized.[[Url]] 设为 value 的url。
-
将 serialized.[[Urn]] 设为 value 的urn。
-
将 serialized.[[SharedStorageContext]] 设为 value 的sharedStorageContext。
-
将 value 的url 初始化为 serialized.[[Url]]。
-
将 value 的urn 初始化为 serialized.[[Urn]]。
-
将 value 的sharedStorageContext 初始化为 serialized.[[SharedStorageContext]]。
注: 为了帮助易于采用,
到 2026 年之前我们将
支持
API navigator.deprecatedReplaceInURN(),
该 API 允许你将
宏代入与给定 urn
uuid 或
FencedFrameConfig
对应的映射 url。
注: 为了帮助易于采用,
在
第三方 cookie 弃用之前
我们将支持 API navigator.deprecatedURNtoURL(),
它会返回
与给定 urn
uuid 或
FencedFrameConfig
对应的映射 url。
typedef (USVString or FencedFrameConfig );UrnOrConfig partial interface Navigator {Promise <undefined >deprecatedReplaceInURN (UrnOrConfig ,urnOrConfig record <USVString ,USVString >);replacements Promise <USVString >deprecatedURNtoURL (UrnOrConfig ,urnOrConfig optional boolean =send_reports false );sequence <USVString >adAuctionComponents (unsigned short ); };numAdComponents
-
TODO: 规范 此内容。 将 macros 中的键替换为 string 中对应的值, 并返回 新字符串。不存在递归替换。
deprecatedReplaceInURN(urnOrConfig, replacements)
方法步骤如下:
-
令 urn 为 null。
-
如果 urnOrConfig 是一个
USVString, 则将 urn 设为 urnOrConfig。 -
否则,将 urn 设为 urnOrConfig 的urn。
-
如果 urn 不是有效的 urn uuid (即不会通过 urn uuid第 3 节中的 ABNF),则抛出一个
TypeError。 -
对于 replacements 中的每个 key → _ 执行:
-
令 p 为一个新的 promise。
-
并行地运行以下步骤:
-
返回 p。
deprecatedURNtoURL(urnOrConfig, send_reports)
方法
步骤如下:
adAuctionComponents(numAdComponents)
-
如果 instance 为 null,则抛出一个
InvalidStateErrorDOMException。 -
如果 this 的相关设置对象的源与 instance 的映射 url的源不是同源,则抛出一个
InvalidStateErrorDOMException。 -
令 maxAdComponents 为 40。
-
如果 numAdComponents > maxAdComponents,则将 numAdComponents 设为 maxAdComponents。
-
返回 adComponentsURNs。
2.4. Fence
接口
若干特定于围栏框架的 API 定义在 Fence 接口上。
enum {FenceReportingDestination ,"buyer" ,"seller" ,"component-seller" ,"direct-seller" , };"shared-storage-select-url" dictionary { // This dictionary has two mutually exclusive modes that aren’t represented as // distinct IDL types due to distinguishability issues: // // When reporting to a preregistered destination (specified by enum), the following // properties are used:FenceEvent DOMString ;eventType DOMString ;eventData sequence <FenceReportingDestination >; // Determines if this data can be sent in a reportEvent() beacon or automatic // beacon that originates from a document that is cross-origin to the mapped // URL of the fenced frame config that loaded this frame tree. // Note that automatic beacon data can only be set from documents that are // same-origin to the fenced frame config’s mapped URL, so this effectively // opts in the data to being used in a cross-origin subframe.destination boolean =crossOriginExposed false ; // When setting event data to be used later in an automatic beacon, the // following properties are used:boolean =once false ; // When reporting to a custom destination URL (with substitution of macros defined by // the Protected Audience buyer), the following property is used:USVString ; };destinationURL typedef (FenceEvent or DOMString ); [ReportEventType Exposed =Window ]interface {Fence undefined reportEvent (optional ReportEventType = {});event undefined setReportEventDataForAutomaticBeacons (optional FenceEvent = {});event sequence <FencedFrameConfig >getNestedConfigs ();Promise <undefined >disableUntrustedNetwork ();undefined notifyEvent (Event ); };event
reportEvent(event) 方法步骤如下:
-
令 document 为 this 的相关全局对象的关联 Document。
-
如果 document 不是完全活动的,则抛出一个
SecurityErrorDOMException。 -
如果 instance 为 null,则返回。
-
如果 instance 的is ad component 为 true,则 返回。
-
如果 instance 的围栏框架报告器 为 null,则返回。
-
令 initiator referrer policy 为 document 的策略容器的referrer 策略。
-
如果 event 是一个
DOMString: -
如果 event 是一个
FenceEvent:-
如果以下所有条件都为 true:
-
event 的
crossOriginExposed为 false,或 instance 的 允许跨源 报告为 false;
则返回。
-
如果 event 具有
destinationURL:-
如果 event 具有
destination或eventType或eventData: -
令 destinationURL 为对
destinationURL运行URL 解析器的结果。 -
-
destinationURL 为 failure;
-
destinationURL 的scheme 不是 "
https";
-
-
使用 instance 的围栏 框架报告器、
buyer、 request initiator、initiator referrer policy,以及一个目标 URL 事件运行报告事件,该事件是 event 的destinationURL。
-
-
否则:
-
如果 event 不具有
destination或 event 不具有eventType: -
令 attributionReportingEnabled 为确定 document 是否被允许使用 "
" 特性的结果。attribution-reporting -
令 attributionReportingContextOrigin 为 document 的上下文源。
-
对于 event 的
destination中的每个 destination 执行:-
使用 instance 的围栏 框架报告器、destination、request initiator、initiator referrer policy,以及一个 目标 枚举事件运行报告事件,该事件具有以下项:
- attributionReportingEnabled
-
attributionReportingEnabled
- attributionReportingContextOrigin
-
attributionReportingContextOrigin
-
-
测试
- fence-report-event.https.html (实时 测试) (源代码)
- fence-report-event-destination-url.https.html (实时 测试) (源代码)
- fence-report-event-cross-origin-content-initiated.https.html (实时 测试) (源代码)
- fence-report-event-cross-origin-nested-urn-iframe.https.html (实时 测试) (源代码)
- fence-report-event-cross-origin-nested.https.html (实时 测试) (源代码)
- fence-report-event-cross-origin-no-embedder-opt-in.https.html (实时 测试) (源代码)
- fence-report-event-cross-origin-no-subframe-opt-in.https.html (实时 测试) (源代码)
- fence-report-event-cross-origin-urn-iframe-content-initiated.https.html (实时 测试) (源代码)
- fence-report-event-cross-origin-urn-iframe-no-embedder-opt-in.https.html (实时 测试) (源代码)
- fence-report-event-cross-origin-urn-iframe-no-subframe-opt-in.https.html (实时 测试) (源代码)
- fence-report-event-cross-origin-urn-iframe.https.html (实时 测试) (源代码)
- fence-report-event-cross-origin.sub.https.html (实时 测试) (源代码)
- fence-report-event-sub-fencedframe.https.html (实时 测试) (源代码)
setReportEventDataForAutomaticBeacons(event)
方法步骤如下:
-
如果 this 的相关全局对象的关联 Document不是完全活动的,则抛出一个
SecurityErrorDOMException。 -
如果 event 不具有
destination或 event 不具有eventType: -
如果 event 的
eventType与任何自动 beacon 事件类型 值都不匹配,则返回。 -
如果 instance 为 null,则返回。
-
如果 this 的相关设置对象的源与 instance 的映射 url的源不是同源,且 event 的
crossOriginExposed为 false,则返回。 -
如果 instance 的围栏框架报告器 为 null,则返回。
-
将 this 的相关全局对象的关联 Document的自动 beacon 数据 映射[event 的
eventType] 设为一个自动 beacon 数据,具有以下 项:- eventData
-
如果已定义且 instance 的is ad component 为 false,则为 event 的
eventData, 否则为空字符串。 - destination
-
event 的
destination - once
-
event 的
once - crossOriginExposed
-
event 的
crossOriginExposed
getNestedConfigs() 方法步骤如下:
-
如果 instance 为 null,则返回。
-
如果 instance 的嵌套配置为 null,则 返回。
-
令 results 为空的由
FencedFrameConfig组成的列表。 -
对于 instance 的嵌套配置中的每个 urn → config 执行:
-
令 newConfig 为在 this 的相关 Realm 中创建的一个新的
FencedFrameConfig对象,具有以下内容:- urn
-
urn
- sharedStorageContext
-
config 的嵌入者 shared storage 上下文
-
将 newConfig追加到 results。
-
-
返回 results。
notifyEvent(event) 方法步骤如下:
-
如果 this 的相关全局对象的关联 Document不是完全活动的,则抛出一个
SecurityErrorDOMException。 -
如果满足以下任一条件,则抛出一个
SecurityErrorDOMException:-
navigable 不是一个围栏可导航体;
-
event 的
isTrusted为 false; -
event 的dispatch flag 未设置;
-
event 的
type不是 "click"
-
-
令 parentNavigable 为 navigable 的非围栏 父级。
-
在给定 parentNavigable 的 活动 window 的情况下,在DOM 操作任务源上排入一个全局任务来运行这些步骤:
-
执行激活通知步骤。
-
在 navigable 的 围栏可导航体容器上触发一个事件,其名称为 "
fencedtreeclick"。 将该事件的bubbles和cancelable属性初始化为true。在运行 内部事件创建 步骤时,将 time 设为一个实现定义的值,该值在此方法的所有调用中保持 一致。
-
disableUntrustedNetwork() 方法步骤如下:
-
令 p 为一个新的 promise。
-
如果 this 的相关全局对象的关联 Document不是完全活动的,则抛出一个
SecurityErrorDOMException。 -
如果 instance 为 null,则返回。
-
如果 this 的相关全局对象的可导航体的可遍历可导航体不是一个围栏可导航体,则用
undefined解析 p 并返回 p。 -
对于每个相关全局对象为 global 的
WebSocket对象 webSocket 执行:给定 webSocket,运行使 WebSocket 连接失败。 -
对于每个相关全局对象为 global 的
WebTransport对象 webTransport 执行:用一个新创建的WebTransportError清理 webTransport,该错误的source为"session"。注: 不传入
WebTransportCloseInfo可确保WebTransport对象被 设为"failed"状态,而不是"closed"状态。 -
并行地运行以下步骤:
-
令 fencedFrameNonce 为 instance 的分区 nonce。
-
令 credentiallessNonce 为 global 的页面 credentialless nonce。
-
以 settings 对 fencedFrameNonce 调用撤销分区 nonce 的网络。
-
如果 credentiallessNonce 非 null,则以 settings 对 credentiallessNonce 调用撤销分区 nonce 的网络。
-
将 instance 的不受信任 网络状态设为disabled for this tree。
-
令 promises 为 instance 的网络 禁用时 promise。
-
给定 global 的浏览上下文的顶级可遍历体,重新计算 所有围栏框架后代的不受信任网络状态。
-
-
返回 p。
-
令 navigables 为 topLevelTraversable 的活动 document的 包含后代可导航体,其中 unfenced 设为 true。
-
-
令 currentNavigable 为从 navigables 弹出的 结果。
-
令 ongoingNavigation 为 currentNavigable 的进行中的导航。
-
如果 currentNavigable 不是一个围栏可导航体:
-
如果 config 的不受信任 网络状态为disabled for this tree and fenced subtrees,且 ongoingNavigation 为 null, 则继续。
-
如果 navigablesWithNetworkChildren 不包含 currentNavigable,且 config 的不受信任 网络状态 为disabled for this tree,则令 networkCutoffReady 为 true;否则为 false。
注: 当某个围栏可导航体 是另一个被确定为尚未准备好进行网络切断的围栏框架的非围栏祖先时,它会被添加到 navigablesWithNetworkChildren。
-
如果 networkCutoffReady 为 true:
-
将 config 的不受信任 网络状态设为disabled for this tree and fenced subtrees。
注: 此时,任何受不受信任网络已禁用这一条件限制的 API 都可以立即使用,即使 promise 尚未完成解析。
-
对于 config 的网络 禁用时 promise中的每个 global → promises 执行:
-
对于 promises 中的每个 promise 执行:
-
在给定 global 的情况下,在DOM 操作 任务源上排入一个全局任务,以 使用
undefined解析 promise。
-
-
-
清空 config 的网络 禁用时 promise。
-
-
如果 networkCutoffReady 为 false 或 ongoingNavigation 非 null:
-
注: Chromium 内部的 Web 平台测试可在 third_party/blink/web_tests/wpt_internal/fenced_frame/disable-untrusted-network-ongoing-navigation.https.html 获取。 一旦 WICG/fenced-frame#192 解决,它将被上游化并在此处链接。
iframe
元素的HTML iframe 元素移除步骤,使其
内容为:
给定
removedNode,
iframe
的HTML 元素移除步骤
为:
-
给定 removedNode,销毁子可导航体。
-
并行地,给定 topLevelTraversable,重新计算 所有围栏框架后代的不受信任网络状态。
-
如果 newValue 为 null,则并行地,给定该 navigable 的 顶级可遍历体,重新计算 所有围栏框架后代的不受信任网络状态。
用户代理具有一个关联的 网络撤销 nonce 集,它是由 分区 nonce组成的集合,以及一个 网络 撤销豁免映射,它是一个映射,其 键是分区 nonce,且值是由 URL 组成的集合。
注: 网络 撤销豁免映射仅用于 Web 平台测试;在正常使用中, 它始终为空。此列表会在 Web 平台测试中通过函数调用直接修改,以 使特定 URL 免于网络撤销。
这需要一个 RFC 来
向 WPT WebDriver 添加仅用于测试的函数。
(WICG/fenced-frame#192)
一旦该 WebDriver 更改完成,现有用于
disableUntrustedNetwork()
的 Chromium 内部 Web 平台测试
需要被上游化并在此处链接。
(WICG/fenced-frame#207)
2.5. 用于网络撤销的猴子补丁
本引言小节是非规范性的。
本节中的网络撤销机制需要修补会发起网络 请求的标准。在我们的补丁之前,这些标准会在不知道最终发起 请求的上下文的网络撤销状态的情况下发起网络请求(例如发起 WebSocket 连接)。我们的补丁会向这些标准中的算法添加检查,以便在发起请求之前考虑发起上下文的网络 撤销状态。有关更多信息,可以找到一些测试这些 API 的非外部 WPT,位于 此处。 这些目前不是外部测试,仅仅是因为网络撤销特性尚未推出。 一旦推出,它们将发布到 WPT 仓库。
网络撤销机制需要对 [FETCH] Standard 作以下猴子补丁。
If should request be blocked due to a bad port, should fetching request be blocked as mixed content, or should request be blocked by Content Security Policy returns blocked, then set response to a network error.
在 "should request be blocked by Content Security Policy" 之后的条件中添加“必须因被撤销的 分区 nonce 而被阻止”。
这需要同时传入 围栏框架 nonce 以及 iframe credentialless nonce(如果存在)。 (WICG/fenced-frame#191)
网络撤销机制需要对 [WebSockets] Standard 作以下猴子补丁。
-
如果给定 client 的全局对象的 可导航体运行确定可导航体是否已为自身撤销网络的结果为 true,则使 WebSocket 连接失败。
网络撤销机制需要对 [WebTransport] Standard 作以下猴子补丁。
-
如果以下任一条件为 true:
-
使用 request 运行请求是否应被 Content Security Policy 阻止?返回 "Blocked";
-
使用 request 运行请求是否应因坏端口而被阻止返回 "blocked";
-
给定 client 的全局对象的可导航体运行确定可导航体是否已为自身撤销网络 返回 true;
则中止剩余步骤,并使用 transport排入一个网络任务以运行这些步骤:
-
网络撤销机制需要对 [Reporting] Standard 作以下猴子补丁。
-
如果 context 是一个
Document, 且给定 context 的节点可导航体运行确定可导航体是否已为自身撤销网络的结果为 true,则返回。
网络撤销机制需要对 [Webpackage] Standard 作以下猴子补丁。
-
如果确定 request 是否必须因被撤销的 分区 nonce 而阻止的结果为 false,则并行地,为 parsedExchange 和 report 等待并排队报告。
2.6. 新的请求目标
fencedframe
的
导航请求处理模型与普通
导航请求有足够多的差异,因此有理由引入一个新的请求目标值。
本规范更新请求目标枚举,以包含一个新
条目 "fencedframe"。对 [FETCH] Standard 执行以下猴子补丁。
将 "fencedframe" 添加到非子资源请求列表以及导航
请求列表。
将 "fencedframe" 添加到 RequestDestination
enum。
A user agent should set value to the first matching statement, if any, switching on request’s destination:
将 "fencedframe" 添加到 switch cases 中,与 "document"、
"frame" 和 "iframe" 并列。
以非规范性的方式,更新 DOM 引言中的目标
表,以说明
fencedframe
导航请求具有以下属性:
2.7. 基于网络撤销限制方法
本引言小节是非规范性的。
在围栏框架完全禁用不受信任网络访问之后,即
disableUntrustedNetwork()
返回的 Promise
已解析后,某些强大的接口方法将
可供在围栏框架内部执行的脚本使用。这些方法在
其他规范中定义,这些规范将使用下面的第一个算法来确定调用是否能够
成功发生。一个受不受信任网络访问撤销限制的方法示例是
在 SharedStorageWorklet
外部调用时的 get()。
该方法
定义在 [Shared-Storage]
草案规范中。
在已调用 disableUntrustedNetwork()
但返回的
Promise
尚未解析的中间状态中,涉及通过网络发起
请求的特性会受到限制。下面的第二个算法用于确定这些特性
是否被允许。
我们区分 "fully revoked" 与 "revoked for self",
因为嵌套的围栏框架树可能仍然具有网络访问权限,并且这些限制不会
应用于它们,直到它们也调用了 disableUntrustedNetwork()。
-
如果 sourceSnapshotParams 的目标围栏框架 配置为 null,则 返回 false。
其意图是 sourceSnapshotParams 的目标围栏框架 配置对于嵌入者发起的
fencedframe导航应为非 null,而在其他情况下为 null。 然而,在此议题 解决之前,这一点并不成立。 -
如果 navigable 的可遍历可导航体的非围栏父级为 null,则返回 false。
注: 当 navigable 的可遍历可导航体的非围栏父级为 null 时,随着 navigable 的围栏 可导航体容器被销毁, navigable 将停止加载。
-
如果以下所有条件为 true:
-
给定 navigable 运行确定可导航体是否已为自身撤销网络的结果为 true;且
-
给定 navigable 的可遍历可导航体的非围栏父级运行确定可导航体是否已为自身撤销网络的结果为 true,
注: 算法确定可导航体是否已为自身撤销网络会在 navigable 以及 navigable 的可遍历可导航体的非围栏父级上运行。这是 因为父围栏框架能够导航一个已经禁用不受信任网络访问的 子围栏框架。如果父围栏 框架在子围栏框架导航刚发起后立即禁用不受信任网络访问, 则该导航必须被阻止。因此该算法必须同时在 父级和子级上运行。否则,如果允许导航提交,父围栏 框架将禁用不受信任网络访问,但子围栏框架不会。
则返回 true。
-
-
否则,返回 false。
2.8. 自动报告
第一个引言段落是非规范性的。
围栏边界模型的一个副作用是,广告将失去得知一次点击
是否导致成功导航的能力。这是因为从围栏框架发起的顶级
导航加载的页面将不被允许向该围栏框架报告它已经
加载(通过类似
window.opener
的方式)。
因此,我们引入
特殊的事件级报告类型,
reserved.top_navigation_start
和
reserved.top_navigation_commit,
当围栏框架发起到
顶级
可遍历体的成功导航时,它们会自动发送一个事件级 beacon。
Document
targetDocument,以及一个
自动 beacon 事件类型
eventType,尝试发送自动 beacon,运行以下步骤:
-
如果 sourceSnapshotParams 的具有瞬态激活被设为 false,则中止这些步骤。
-
令 config 为 sourceSnapshotParams 的发起者围栏 框架配置实例。
-
如果 config 为 null,则中止这些步骤。
注: 由于此算法会无条件地针对所有导航调用, 这用于捕获到顶级可遍历体的导航并非源自
fencedframe的情况。 -
如果 config 的is ad component 为 false,则令 request initiator 为 sourceOrigin;否则为 sourceSnapshotParams 的发起者祖先根 源。
-
如果 config 的is ad component 为 false,则令 initiator referrer policy 为 sourceSnapshotParams 的源策略容器的referrer 策略;否则为 sourceSnapshotParams 的发起者 祖先根 referrer 策略。
-
如果 sourceOrigin 与 config 的映射 url的源不是同源,则令 isCrossOrigin 为 true;否则为 false。
-
如果 isCrossOrigin 为 false,则令 beaconMapping 为 sourceSnapshotParams 的快照自动 beacon 存储的数据映射; 否则为 sourceSnapshotParams 的快照自动 beacon 存储的 跨源 暴露数据映射。
-
令 beaconData 为 beaconMapping[eventType]。
-
令 automaticBeaconsAllowed 为 sourceSnapshotParams 的允许自动 beacon。
注: 这会跟踪是否通过 `
Allow-Fenced-Frame-Automatic-Beacons` 标头进行了选择加入。当此值为 false 时,对于同源 document 或通过设置数据选择加入的 document, 仍然可以发送自动 beacon。 -
如果 beaconData 为 null 且 automaticBeaconsAllowed 为 false,则中止这些 步骤。
-
如果 isCrossOrigin 为 true 且 automaticBeaconsAllowed 为 false,则中止这些 步骤。
-
对于 config 的围栏框架报告器的 围栏框架 报告元数据引用的 围栏框架报告映射的键中的每个 destination 执行:
-
使用 config 的围栏框架 报告器、destination、request initiator、 initiator referrer policy,以及一个 自动 beacon 事件运行报告 事件,该事件具有以下项:
- 类型
-
eventType
- 数据
-
如果 beaconData 为 null,则为空字符串;否则为 beaconData 的eventData。
- attributionReportingEnabled
-
sourceSnapshotParams 的已启用 attribution reporting
- attributionReportingContextOrigin
-
sourceSnapshotParams 的attribution reporting 上下文源
-
-
如果 beaconData 的once 为 true,则将 beaconMapping[eventType] 设为 null。
测试
- automatic-beacon-anchor-click-handler.https.html (实时 测试) (源代码)
- automatic-beacon-click-handler.https.html (实时 测试) (源代码)
- automatic-beacon-two-events-clear.https.html (实时 测试) (源代码)
- automatic-beacon-two-events-persist.https.html (实时 测试) (源代码)
- automatic-beacon-unfenced-top.https.html (实时 测试) (源代码)
- automatic-beacon-no-destination.https.html (实时 测试) (源代码)
- automatic-beacon-no-opt-in.https.html (实时 测试) (源代码)
- automatic-beacon-shared-storage.https.html (实时 测试) (源代码)
- automatic-beacon-cross-origin-false.https.html (实时 测试) (源代码)
- automatic-beacon-cross-origin-navigation.https.html (实时 测试) (源代码)
- automatic-beacon-cross-origin-no-data.https.html (实时 测试) (源代码)
- automatic-beacon-cross-origin-no-opt-in.https.html (实时 测试) (源代码)
- automatic-beacon-use-ancestor-data.https.html (实时 测试) (源代码)
- automatic-beacon-data-cross-origin-ancestor.sub.https.html (实时 测试) (源代码)
- automatic-beacon-data-set-by-sibling.https.html (实时 测试) (源代码)
- automatic-beacon-data-multiple-ancestors.https.html (实时 测试) (源代码)
-
给定 sourceSnapshotParams、initiatorOriginSnapshot、 navigable 关联的
Document和reserved.top_navigation_start,尝试发送自动 beacon。
-
如果 failure 为 false,则:
-
给定 sourceSnapshotParams、entry 的document state 的发起者源、 document 和
reserved.top_navigation_commit,尝试发送自动 beacon。 -
给定 sourceSnapshotParams、entry 的document state 的发起者源、 document 和
reserved.top_navigation,尝试发送自动 beacon。
-
3. HTML 集成
3.1. 对 Window
接口的扩展
partial interface Window { // Collection of fenced frame APIsreadonly attribute Fence ?fence ; };
每个 Window
对象都有一个关联的 fence,它是在创建该 Window
时一并创建的 Fence 实例。
fence getter 步骤如下:
3.2. Document
支持概念
我们首先建立一些初步类型:
- eventData
-
一个字符串
- destination
-
一个由
FenceReportingDestination组成的列表 - once
-
一个布尔值
- crossOriginExposed
-
一个布尔值
自动 beacon 数据映射是一个映射,其键 是 自动 beacon 事件类型,且其值是 null 或一个 自动 beacon 数据。
- 数据映射
- 跨源 暴露数据映射
每个 Document
对象都有一个关联的 自动 beacon 数据映射,
它是一个自动 beacon 数据映射。
每个 Document
对象都有一个关联的 允许自动 beacon,它
是一个布尔值,初始为
false。
3.3. 对创建浏览上下文的修改
-
If creator is non-null, then:
改为使用更严格的条件:
-
If creator is non-null and embedder is not a
fencedframeelement, then:
注: 这是因为我们需要确保不会跨围栏框架 边界泄露 creator 的referrer、源、document 基 URL、策略容器。
向此算法第 4 步(上面已修改)添加一个子步骤,内容为:
3.4. 策略容器继承
当向本地
URL发起导航请求时,
iframe
会从导航
请求的发起者 Document
克隆其
策略容器。
如果
fencedframe
也做同样的事情,则会允许关于发起者
策略容器的信息跨围栏框架
边界泄露。本节会修补
策略容器继承,以关闭该泄漏。
重写第 3 步,内容为:
-
如果 responseURL 为本地,initiatorPolicyContainer 不是 null,且 fenced 为 false, 则返回 initiatorPolicyContainer 的一个克隆。
注: 我们不需要修改
responseURL 是
about:srcdoc
的情况,
因为围栏框架不支持导航到
about:srcdoc。
-
如果 navigable 是一个围栏可导航体,则令 fenced 为 true; 否则为 false。
注: 这确保无论发起者
Document是 navigable 的活动 document 还是其非围栏 父级,fenced 都为 true。
重写第 23 步(现在是第 24 步),内容为:
-
令 resultPolicyContainer 为给定 response 的URL、 entry 的document state的历史策略容器、 sourceSnapshotParams 的源策略容器、null、 responsePolicyContainer 和 fenced,确定导航参数 策略容器的结果。
注:
fencedframe
在初始 Document
创建时的策略容器继承会在
§ 3.3 对创建浏览上下文的修改
一节中处理。
3.5. 嵌套可遍历体
3.5.1. 引言
本节是非规范性的。
[HTML] Standard 将可导航体组织为两类:子可导航体和
可遍历可导航体(也称为顶级可遍历体)。像围栏框架这样的特性
的引入,以及在较小程度上 portals 的引入,
通过添加一种新的可遍历可导航体类型,使这个模型复杂化;这种类型有时像
子可导航体。由于这些新的框架类型位于与其嵌入者分离的
浏览上下文组中,因此期望并要求某种具体层级的隔离;另一方面,
由于它们在视觉上组合在其他浏览上下文组内部,所以它们有时
需要像我们在例如
iframe
中看到的普通子可导航体那样表现。
这里的复杂性在于决定诸如可导航体容器、 可导航体父级和后代可导航体等术语何时需要跨越 可遍历可导航体/浏览上下文组边界,而何时这样做会 不安全或不正确。下面的示例说明了这一点。
当用户
激活一个 Document
内部的内容时,
通常激活通知步骤会向所有
祖先可导航体以及所有同源
后代可导航体赋予用户激活。但是,
因为
fencedframe
可以托管需要与其嵌入者隔离的敏感内容,
并且因为用户激活和消耗在这两方之间提供了通信
向量,所以就用户激活而言,
fencedframe
的
围栏可导航体不能被视为其
嵌入者的后代,其嵌入者也不能被视为
fencedframe
的
围栏可导航体的祖先,不能按用户激活算法当前使用这些术语的方式来理解。换句话说,我们认为用户激活是围栏化的,
以表示它永远不会跨越
围栏可导航体边界;如果它是非围栏化的,它将
像在
iframe
中那样表现,
允许用户激活在框架
边界之间自由流动。
不同于用户激活,当
fencedframe
的
围栏可导航体被创建或导航时,它必须继承其嵌入者
Document
的
活动沙盒化标志集,这与普通
子可导航体中 Document
的标准行为一致。如果我们不这样做,那么
fencedframe
元素将成为一个轻易的
sandbox 绕过。因为
fencedframe
sandbox 标志继承的行为类似于它在
iframe
元素中的行为,我们认为 sandbox 继承是非围栏化的。
为了提供上面提到的隔离及其有条件的放松,本规范为可遍历可导航体定义了一种新的父级,称为非围栏父级,它提供到其 嵌入者的链接,算法在需要非围栏化时可以有意使用该链接,如上所述。
注: 引入一种新的父级(非围栏父级)是一项有意的
设计决策。这意味着默认情况下,
fencedframe
边界是私有且隔离的,
因为默认情况下 Web 平台中没有任何内容会从
fencedframe
的
围栏可导航体遍历到其嵌入者。在
修改算法以使它们能够跨越
fencedframe
围栏可导航体边界时,必须谨慎,
并且此类每项修改都将
独立评估,并出现在本规范中。
本节其余部分为各种处理相关可导航体集合的 [HTML] 定义(及其用法)提供补丁,目的是适当地对 Web 平台的各个部分 进行围栏化和非围栏化。
3.5.2. 可遍历可导航体
-
一个 非围栏父级,即一个可导航体或 null,初始为 null。
注: 非围栏父级链接赋予
fencedframe
的
围栏可导航体到其嵌入者的链接,
该链接会被谨慎用于
需要 "非围栏化" 的事物,例如焦点处理模型中的某些算法。
注: 此算法与可遍历可导航体的非围栏父级 getter 不同,因为此 算法首先会在 navigable 是普通子可导航体时,尝试获取该可导航体的 普通父级。
-
令 parentNavigable 为 navigable 的非围栏 父级。
-
返回 parentNavigable 的活动 document。
3.5.3. 嵌套可遍历体
在 [HTML] 的可导航体 一节中,添加一个标题为 "Nested traversables" 的新小节,其中包含以下文本、定义和 算法。
类似于可导航体容器及其各自的内容可导航体,
其他元素(到目前为止,仅
fencedframe
元素)会向
用户呈现一个更隔离的可导航体。这些元素称为 围栏可导航体容器。
围栏可导航体容器具有一个 围栏 可导航体,它要么是一个具有非 null 非围栏父级的可遍历可导航体,要么为 null。它初始为 null。
-
令 group 为一个新的浏览上下文组。
注: 似乎没有理由像创建新的浏览上下文组和 document那样,将 group追加到用户代理的浏览上下文组集合。
-
令 document 为给定 element 的节点 document、element 和 group,运行创建新的浏览上下文和 document 的第二个返回值。
-
令 documentState 为一个新的document state,其document 是 document。
-
令 traversable 为一个新的可遍历可导航体。
-
令 parentNavigable 为 element 的节点可导航体。
-
给定 documentState 和 parentNavigable,初始化嵌套可遍历体 traversable。
-
将 element 的围栏可导航体设置为 traversable。
-
令 initialHistoryEntry 为 traversable 的活动会话历史条目。
-
将 initialHistoryEntry 的step 设为 0。
-
返回 traversable。
注: 创建新的 嵌套可遍历体算法会创建第一种不是顶级可遍历体的可遍历可导航体。这将 需要移除 [HTML] 的顶级 可遍历体一节中关于嵌套可遍历体的注释。
3.5.4. 顶级可遍历体
[HTML] Standard 当前 将顶级可遍历体定义为一个可遍历可导航体, 其父级为 null,然而这是一个不充分的定义,本 规范会修改它。[HTML] 提到,在本规范之外,所有可遍历可导航体都是顶级可遍历体,但它 “设想”未来规范可能会想要 创建一种嵌套的可遍历体,并通过非 null 的父级实现嵌套;因此,顶级可遍历体 与可遍历可导航体之间的区别依赖于父级是否为 null。
本规范提出的围栏可导航体,正是 [HTML] 在为顶级可遍历体 和可遍历可导航体之间的区别留出空间时所设想的内容,然而本规范不会 为围栏可导航体使用 父级指针,原因如上文所述 (它们改为使用非围栏父级指针)。这意味着在 默认情况下,顶级可遍历体和 围栏可导航体都具有 null 的父级,这会使 这种区别失去意义。
为了修补顶级可遍历体和围栏可导航体之间预期的区别,请按如下方式修补以下 定义:
注: 采用这些新定义后,顶级 可遍历体本质上是§ 3.5.1 引言中所述的“非围栏化”的。
3.6. 对可导航体遍历算法的修改
3.7. 对焦点算法的修改
[HTML] Standard 定义了如何
处理元素和 Window
的聚焦,
包括通过用户手势
以及通过脚本发起的 API。由于围栏框架被设计为防止跨
围栏框架边界的通信,我们需要谨慎处理聚焦。这是因为当焦点跨越
fencedframe
边界时,边界两侧的上下文都能检测到该变化,这可能被
用来在
fencedframe
与其嵌入者之间打开通信信道。
我们通过不允许聚焦步骤将脚本发起的焦点移过围栏 框架边界来实现这一点。
当用户
点击
button
之类的元素,该元素位于
fencedframe
内部,而另一个位于
fencedframe
外部的元素正处于聚焦状态时,
聚焦步骤会允许该
button
获得焦点,因为这明确是一个
用户发起的操作。若不允许这样做,则
fencedframe
内部的任何元素都永远无法
获得焦点。
如果我们
继续像本规范之前的现状那样,允许所有元素都通过 focus()
方法被
聚焦,则一个围栏可导航体容器及其围栏可导航体可以使用一系列
focus()
调用来跨
围栏框架边界发送任意数据,这是一种隐私泄漏。为避免这种情况,我们实际上会“围栏化”
focus()
方法,它为了隐私牺牲了一些功能。
在算法第 3 步(会改变新的焦点目标)之后添加一个新步骤,内容为:
-
如果 new focus target 是一个围栏可导航体容器,且具有非 null 的 围栏可导航体,则将 new focus target 设为该 围栏可导航体的活动 document。
在定义 new chain 变量的步骤之后添加一个新步骤,内容为:
-
如果 unfenced 为 false,new chain 包含一个
Documentdocument,其节点可导航体的可遍历可导航体是一个 围栏可导航体,且 old chain 并不也 包含 document,则返回。注: 这就是在焦点尝试跨越围栏时,我们如何在调用 焦点更新步骤之前提前退出。
修改聚焦步骤中算法步骤之后的用户代理句子,使其内容为:
每当用户尝试将焦点移动到 candidate 时,用户代理必须立即对一个可聚焦区域或 可导航体 candidate 运行聚焦步骤,并将 unfenced 设为 true。
-
在该元素上触发一个
click事件。
当用户激活一个点击可聚焦的可聚焦区域时,用户代理必须
对该可聚焦区域运行聚焦步骤,并将 focus trigger 设为
"click",且将 unfenced 设为 true。
-
如果 previouslyFocusedElement 不是 null,则:
注: 尽管手动关闭 popover 是一个 用户发起的手势, 聚焦步骤仍会在 unfenced 设为 false 的情况下被调用, 无论这是通过用户手势调用还是通过脚本调用。
-
用户代理可以在此过程中通过为该元素运行 聚焦步骤来聚焦其中一个元素,并且可以改变 document 的滚动位置,或者执行其他某种将该元素引起用户注意的操作。 如果这些步骤是由用户手势调用的,则聚焦步骤可以在 unfenced 设为 true 的情况下调用。对于 与表单关联的自定义元素,用户代理 应改为使用其FACE 验证锚点, 以用于这些操作的目的。
-
如果 currentObject 是一个可聚焦区域,则将 currentObject 设为 currentObject 的DOM 锚点的节点 document。
否则,如果 currentObject 是一个
Document, 其节点可导航体的父级 非 null,则将 currentObject 设为 currentObject 的节点可导航体的 父级。否则,如果 currentObject 是一个
Document, 其节点可导航体是一个可遍历可导航体,且其非围栏父级非 null,则 将 currentObject 设为 currentObject 的节点可导航体的非围栏父级。否则,中断。
注: 此算法可以无条件“跳过围栏” 边界,因为其返回值总是 会输入到一个确实会谨慎考虑围栏边界的算法中。
-
如果 candidate 是一个可导航体容器,且具有非 null 的 内容可导航体,则令 new candidate 为使用 candidate 的 内容可导航体作为第一个参数、 direction 作为 第二个参数,并以 sequential 作为第三个参数运行 顺序导航搜索 算法的结果。
如果 candidate 是一个围栏可导航体容器,且具有非 null 的 围栏可导航体,则令 new candidate 为使用 candidate 的 围栏可导航体作为第一个 参数、 direction 作为第二个参数,并以 sequential 作为第三个参数运行 顺序导航搜索 算法的结果。
如果 new candidate 为 null,则令 starting point 为 candidate,并返回到此算法的开头。否则,令 candidate 为 new candidate。
测试
3.8. 导航
本节描述
fencedframe
元素如何与极其复杂的导航过程交互,该过程包括与各种标头、隔离机制和策略的集成。
3.8.1.
`Supports-Loading-Mode` HTTP
响应标头
本节旨在对 [HTML] Standard 进行猴子补丁,然而由于
`Supports-Loading-Mode` 标头
尚未合并到 [HTML]
中,
而是存在于 [Prerendering-Revamped] 规范中,因此本节实际上
是对该猴子补丁规范进行猴子补丁。
将下面新的token添加到 `Supports-Loading-Mode` 响应
标头的有效token列表中:
`fenced-frame`
token 表示
该响应可用于在围栏可导航体内创建一个 Document。
如果没有这种显式选择加入,则围栏可导航体内的所有导航都将失败,如
§ 3.8 导航中所述。
3.8.2.
`Allow-Fenced-Frame-Automatic-Beacons`
HTTP 响应标头
提供一个 document 资源,该资源被加载到一个 Document
中,而该 Document 与其浏览上下文的围栏框架配置
实例的映射 url不是同源,同时带有 Allow-Fenced-Frame-Automatic-Beacons
HTTP 响应标头,会使该
Document
选择加入:当它执行导航时触发自动 beacon 事件。此标头是一个
结构化标头,其值必须是一个布尔值。
3.8.3.
`Allow-Cross-Origin-Event-Reporting`
HTTP 响应标头
提供一个 document 资源,该资源由具有 Allow-Cross-Origin-Event-Reporting
HTTP
响应标头的围栏框架配置实例加载到
fencedframe
中,会使该 Document
的
跨源子可导航体选择加入,使其能够发送
reportEvent()
beacon。此标头是一个结构化
标头,其值必须是一个
布尔值。
3.8.4. COOP、COEP 和跨源隔离
在本规范之外,`Cross-Origin-Opener-Policy`
标头仅应用
于顶级
可遍历体而非所有可导航体,并且本规范延续了这一
意图,即此标头不会影响围栏可导航体,也不会从其嵌入者继承。
因此,托管在围栏可遍历可导航体内的浏览上下文组
的跨源隔离模式始终会被设为 "none"。
不过,围栏可导航体会遵守其非围栏父级的嵌入者策略,这通过以下内容实现:
注: 这会导致
fencedframe
内部的导航在未提供合适的
`Cross-Origin-Embedder-Policy` 标头时失败,就像
iframe
的行为一样。
确定我们是否需要 围栏化或非围栏化排入跨源嵌入者 策略继承违规算法,因为让它非围栏化可能会造成隐私泄漏。
确定我们是否需要 围栏化或非围栏化排入跨源嵌入者 策略 CORP 违规报告算法,因为让它非围栏化可能会造成隐私泄漏。
测试
3.8.5. 实际导航变更
- 发起者 围栏框架配置实例
-
一个围栏框架配置实例或 null, 初始为 null。
- 发起者祖先根 源
-
一个源或 null,初始为 null。
- 发起者 祖先根 referrer 策略
-
一个referrer 策略或 null,初始为 null。
- 目标围栏框架 配置
-
一个围栏 框架配置或 null,初始为 null。
注: 发起者围栏框架
配置实例是加载到导航发起者浏览上下文中的围栏框架配置实例,如果存在的话。
对于组件广告,发起者祖先根
源是顶级广告容器的源(如果存在)。对于组件广告,发起者祖先根
referrer 策略是顶级广告容器的 referrer 策略(如果存在)。
如果由
fencedframe
发起的
导航成功,它们会被尝试发送自动 beacon算法用于比较
源,并确定要向哪些 FenceReportingDestination
发送 beacon,以及附带什么
信息。另一方面,目标围栏框架配置是未实例化的围栏框架配置,它会在
以围栏框架为目标的导航中加载到
fencedframe
元素中。
这些字段之间并不会以任何有意义的方式相互交互。
Document
sourceDocument,快照自动 beacon 数据映射:
-
令 info 为一个新的空快照自动 beacon 存储。
-
令 mapping 为 info 的数据映射。
-
令 crossOriginMapping 为 info 的跨源 暴露数据映射。
-
令 current navigable 为 sourceDocument 的节点可导航体。
-
当 current navigable 不是 null 时循环:
-
对于 current navigable 的活动 document的自动 beacon 数据 映射中的每个 type → data 执行:
-
如果 mapping[type] 不存在,则将 mapping[type] 设为 data。
注: 这保证了第一个包含特定类型自动 beacon 数据的 祖先可被发起导航的 document 使用。这也会 防止某个祖先阻止 document 使用在更高层祖先中设置的数据。
-
如果 crossOriginMapping[type] 不存在,且 data 的crossOriginExposed 为 true,则将 crossOriginMapping[type] 设为 data。
-
-
将 current navigable 设为 current navigable 的父级。
-
-
返回 info。
注: 存储在 info 中的映射意在
保存对原始 Document
的
自动 beacon 数据映射的引用,这些映射
被用来构造 info。稍后会在尝试发送自动 beacon中修改这些映射,以清除
任何 once 设为 true 的 beacon 数据。
Document
sourceDocument 的发起者的围栏曾祖先的
可导航体:
-
令 navigable 为 sourceDocument 的节点可导航体。
-
当 navigable 不是 null 且 navigable 不是围栏可导航体时:
-
将 navigable 设为 navigable 的父级。
-
-
如果 navigable 为 null,则返回 null。
-
将 navigable 设为 navigable 的非围栏 父级。
-
当 navigable 不是 null 且 navigable 不是围栏可导航体时:
-
将 navigable 设为 navigable 的父级。
-
-
返回 navigable。
fencedframe
内部的 Document,
此算法会获取该 document 最近的围栏框架祖先的最近围栏框架祖先的可导航体。如果不存在这样的“围栏
框架曾祖先”,则该算法返回 null。因此,只有当给定 Document 至少位于一个本身也位于
围栏框架中的围栏框架内时,此算法才会返回一个可导航体。例如,对于给定的框架树结构:
Main frame (origin A)
<fencedframe> (origin B)
<iframe> (origin C)
<fencedframe> (origin D)
<iframe> (origin E)
<fencedframe> (origin F)
给定每个 document 时,该算法将返回以下内容:
-
Main frame (origin A)将返回null。 -
<fencedframe> (origin B)将返回null。 -
<iframe> (origin C)将返回null。 -
<fencedframe> (origin D)将返回<fencedframe> (origin B)。 -
<iframe> (origin E)将返回<fencedframe> (origin B)。 -
<fencedframe> (origin F)将返回<fencedframe> (origin D)。
- 发起者围栏 框架配置实例
- 发起者祖先根 源
-
如果在 sourceDocument 上运行获取发起者的围栏 曾祖先的可导航体的结果为 null,则为 null。否则,为 sourceDocument 的发起者的围栏 曾祖先的可导航体的 活动 document的源。
- 发起者祖先 根 referrer 策略
-
如果在 sourceDocument 上运行获取发起者的围栏 曾祖先的可导航体的结果为 null,则为 null。否则,为 sourceDocument 的发起者的围栏 曾祖先的可导航体的 活动 document的策略容器的referrer 策略。
- 已启用 attribution reporting
-
确定 sourceDocument 是否被允许使用 "
" 特性的结果attribution-reporting - attribution reporting 上下文源
-
sourceDocument 的上下文源
- 允许自动 beacon
-
sourceDocument 的允许自动 beacon
- 快照自动 beacon 存储
-
在 sourceDocument 上运行快照自动 beacon 数据 映射的结果。
-
document 的相关全局对象的可导航体是一个围栏可导航体;
注: 这确保
fencedframe内部的所有导航都会以 "replace" 模式进行,无论发起者是谁。
测试
- history-back-and-forward-should-not-work-in-fenced-tree.https.html (实时 测试) (源代码)
- history-length-fenced-navigations-replace-do-not-contribute-to-joint.https.html (实时 测试) (源代码)
- history-length-outer-page-navigation-not-reflected-in-fenced.https.html (实时 测试) (源代码)
- history-length-outer-page-navigation-not-reflected-in-fenced-nested-iframe.https.html (实时 测试) (源代码)
在 [HTML] 的navigate 算法第 5 步之后添加一个步骤,内容为:
-
如果给定 sourceDocument 的节点可导航体运行确定可导航体是否已为自身撤销网络的结果为 true,则返回。
修改 [HTML] 的navigate 算法第 13 步("If all of the following are true:"),以 包含以下条件:
-
sourceDocument 的节点可导航体不是一个围栏 可导航体容器, 同时 navigable 是一个围栏可导航体。
注: 这确保嵌入者发起的 导航永远不会触发
fencedframe内部的片段导航。
将这些步骤插入到第 22 步,即并行地执行的步骤之后,使得 后续内容成为已修补算法中最先并行地运行的步骤:
-
如果 url 是一个urn uuid 且 navigable 是一个围栏可导航体:
-
令 config 为在 sourceDocument 的节点可导航体的可遍历可导航体的围栏框架配置 映射中查找配置的结果。
注: 这可能会“等待” 任意长时间,直到与 urn uuid url 关联的 config 在围栏框架配置 映射中“完成”。这就是为什么此步骤并行地运行。若随后发生任何嵌入者发起的导航,则该导航应 通过通常跟踪进行中的导航的机制被取消。
-
将 config 的嵌入者 shared storage 上下文设为 sharedStorageContext。
-
将 sourceSnapshotParams 的目标围栏框架 配置设为 config。
-
运行 config 的导航时回调中的步骤。
-
-
如果 navigable 是一个围栏可导航体,且 sourceDocument 的节点可导航体位于 navigable 的活动 document的祖先可导航体中,且 unfenced 设为 true:
将以 "Let unloadPromptCanceled be the result of" 开头的步骤重写为:
-
如果 navigable 是一个围栏可导航体,则令 unloadPromptCanceled 为 false;否则为对 navigable 的 活动 document的包含后代可导航体检查卸载是否被用户取消的结果。
在第 22.8.2 步(Let finalSandboxFlags be the union...)之后添加一个步骤,内容为:
下面的补丁使用此前已赋值的目标围栏框架配置,并实例化 它,以便在导航 最终完成时使用。
最后,下面的补丁使用导航参数的围栏框架配置实例,并 处理由导航发起的浏览上下文的围栏框架配置实例赋值。
注: 浏览上下文的围栏框架配置实例会以两种
不同方式赋值:(1) 在嵌入者发起的
fencedframe
导航期间赋值,如本节其余部分
所述;以及 (2) 在可遍历可导航体是围栏可导航体的
子可导航体中,为 Document
初始创建期间继承,如§ 3.3 对创建浏览上下文的修改一节中处理的那样。
对于
fencedframe
内部的任何成功导航,
无论它是由
fencedframe
中的内容发起,还是由其嵌入者发起,都恰好会发生以下两种情况之一:
-
如果 navigationParams 的围栏框架配置 实例不是 null:
在第 9 步之后添加一个新步骤,内容为:
-
令 automaticBeaconsAllowed 为在 navigationParams 的响应的标头列表上 给定 `
Allow-Fenced-Frame-Automatic-Beacons` 和 "item",运行获取结构化字段值的结果。
进一步重写第 10 步(现在为第 12 步),以返回一个带有额外参数的新 Document:
- 允许自动 beacon
-
automaticBeaconsAllowed。
-
给定 navigable 和 sourceSnapshotParams 运行确定 嵌入者发起的围栏框架导航是否应被阻止的结果为 true;
3.8.6. 浏览上下文组交换
当
fencedframe
的嵌入者在该框架内部发起导航时,我们必须执行一次
浏览上下文组交换,以完全重置该框架内部的上下文,
确保没有任何遗留内容会泄漏给下一个 Document。
-
如果以下所有条件为 true:
-
navigable 是一个围栏可导航体;
-
sourceSnapshotParams 的fetch 客户端不是 navigable 的活动 document的相关设置对象;
-
navigationParams 非 null
则将 navigationParams 的COOP 强制执行结果的需要浏览上下文组切换布尔值设为 true。
这确实 可行,但我们应考虑使用一种单独机制来完成此事, 而不是搭载在 COOP 机制之上;COOP 机制在设计时并未考虑围栏框架, 并且可能会以给本规范带来不期望副作用的方式演进。
-
3.8.7.
"_unfencedTop" 导航目标
围栏框架使用一个额外的保留导航目标 "_unfencedTop" 来导航。
本节修补 [HTML] 规范的相关部分,以添加对这个新的
保留关键字的支持。
_unfencedTop" 的新关键字。
修改下面的段落,以将以下文本替换掉:
-
"top" means the top-level traversable of the navigable that the link or script is in,
替换为:
注: 这一更改是必要的,因为本规范 添加了 可遍历可导航体和顶级可遍历体之间的区别,而二者此前 在功能上是等价的。
在下面的表格中,添加一个名为 "Effect in a fenced frame" 的列。此列中所有现有 行的值都与 "ordinary effect" 相同。然后,添加两行,其内容为:
| 关键字 | 普通效果 | 在具有……的 iframe 中的效果
| 在 fencedframe 中的效果>
| |
|---|---|---|---|---|
sandbox=""
| sandbox="allow-top-navigation"
| |||
如果 outermost top 是 current,则为 _unfencedTop
| new | maybe new | maybe new | current |
如果 outermost top 不是 current,则为 _unfencedTop
| new | maybe new | maybe new | outermost top |
6.5. 否则,如果 name 与 "_unfencedTop" 进行 ASCII 大小写不敏感匹配,且
currentNavigable 的可遍历可导航体是一个围栏可导航体,则将
chosen 设为 currentNavigable 的顶级可遍历体。
3.9. 页面可见性
修改 Page visibility 一节(位于 [HTML]), 使得当用户代理更改一个 可遍历可导航体的系统可见性状态时运行的算法第一步,会调用包含后代可导航体算法,并将 unfenced 设为 true。
3.10. 事件
3.10.1.
onfencedtreeclick
事件处理器
修改
元素、Document 对象和 Window 对象上的事件处理器一节(位于 [HTML])中的表格,以包含一个新行。
| 事件处理器 | 事件处理器事件类型 |
|---|---|
onfencedtreeclick
| fencedtreeclick
|
修改 GlobalEventHandlers
接口如下:
partial interface mixin GlobalEventHandlers {attribute EventHandler ; };onfencedtreeclick
此外,修改 可在任何 HTML 元素上指定的事件处理器内容属性 列表(位于 [HTML]),以包含一个 新行:
3.10.2.
fencedtreeclick
事件类型
修改 Events 表格(位于 Index
一节,属于 [HTML]),以
包含一个新行。
| 事件 | 接口 | 相关目标 | 描述 |
|---|---|---|---|
fencedtreeclick
| Event
| 元素 |
在一个
fencedframe
元素的
围栏可导航体的 Document
调用 notifyEvent()
后异步触发
|
4. 与其他规范的交互
由于
fencedframe
元素及其与可导航体和浏览上下文组等核心概念的交互,必然具有横切性质,因此有许多
规范依赖的术语,其用法必须结合本规范重新评估;
本节容纳我们提议对其他规范作出的各种更改。
4.1. 预渲染
Prerendering Revamped 规范定义了可导航体的加载模式及其可取值。我们的 规范为围栏框架添加了另一个值:
- "
fencedframe" -
此可导航体正在显示
fencedframe的 内容
4.2. 内容安全策略
本引言小节是非规范性的。
通常,Content Security Policy [CSP] 可由与托管可导航体容器的
Document
关联的 Web 内容使用,以限制子可导航体中导航的来源。
为了防止 [CSP]
被用作通信侧信道,向运行其嵌入者的站点暴露
fencedframe
内部导航的
URL,能够影响
fencedframe
导航的唯一源
表达式是:
-
scheme-source "
https:" -
host-source "
https://*:*" -
字符串 "
*"
请参见描述此内容的CSP 解释文档。
4.2.1. 算法
接下来,我们修改 [CSPEE] 规范的行为。如果嵌入框架指定了 必需 CSP,围栏框架将不会加载。这样做是为了 防止从嵌入者到围栏框架的任意数据流。
4.2.2. 新的 fenced-frame-src [CSP] 指令
由于
fencedframe
是不同于
iframe
的元素,
使用 frame-src
指令无法让网站对其 CSP 规则拥有足够控制。引入一个新的 [CSP]
指令:fenced-frame-src。下面给出被猴子补丁修补后的规范:
fencedframe
的
围栏可导航体中的 URL。该
指令的
名称和值的语法由以下 ABNF 描述:
directive-name = "fenced-frame-src" directive-value = serialized-source-list
Content-Security-Policy: fenced-frame-src https://example.com/
以下代码的获取将返回网络错误,因为提供的 URL 与
fenced-frame-src 的源
列表不匹配:
< fencedframe src = "https://example.org/" > </ fencedframe >
Content-Security-Policy: connect-src 'self'; ... worker-src 'self'
现在将表述为:
Content-Security-Policy: connect-src 'self'; ... fenced-frame-src 'self'; ... worker-src 'self'
- "
fenced-frame-src" -
-
返回
<< "fenced-frame-src", "frame-src", "child-src", "default-src" >>。
-
- "
fencedframe" -
-
返回
fenced-frame-src。
-
测试
- ancestor-throttle.https.html (实时 测试) (源代码)
- csp-allowed.https.html (实时测试) (源代码)
- csp-blocked.https.html (实时测试) (源代码)
- csp-fenced-frame-src-allowed.https.html (实时 测试) (源代码)
- csp-fenced-frame-src-blocked.https.html (实时 测试) (源代码)
- csp-frame-src-allowed.https.html (实时 测试) (源代码)
- csp-frame-src-blocked.https.html (实时 测试) (源代码)
- csp-allowed-transparent.https.html (实时 测试) (源代码)
- csp-blocked-transparent.https.html (实时 测试) (源代码)
- csp.https.html (实时测试) (源代码)
- cspee.https.html (实时测试) (源代码)
- embedder-csp-not-propagate.https.html (实时 测试) (源代码)
4.3. 权限策略
本引言小节是非规范性的。
可用于
fencedframe
内部 Document
的
受策略控制的特性,
以及计算它们的方式,会根据
fencedframe
导航到的围栏框架配置如何构造而变化。
通过 Web 平台上的 FencedFrameConfig
构造器创建的围栏框架配置实例将具有灵活的权限策略行为,且它所导航的
fencedframe
的内部
Document
只要权限属于围栏框架
允许权限列表,就会被允许继承这些权限。所有
其他受策略控制的特性都将被禁用。
通过会设置其有效启用权限的
配置生成 API 创建的围栏框架配置实例将
具有固定的
权限策略行为,且它所导航到的
fencedframe
的内部
Document
将把有效启用权限作为将在该 Document
中启用的
受策略控制的特性的唯一
列表(其他所有特性都将被
禁用)。
在
fencedframe
导航到具有固定权限策略行为的围栏框架配置实例期间,它会将
正在导航到的围栏框架配置实例的有效启用
权限与产生的 Document
的
权限策略的继承策略进行比较。只有当每个继承策略值为 "Enabled" 的继承特性,也
出现在有效启用
权限围栏框架配置实例中时,该导航才会成功。否则,
嵌入
fencedframe
的环境会被视为不适合该围栏框架配置,
并且导航会被阻止。
同时,为确保
fencedframe
的
嵌入者不会根据该导航的源直接影响框架中的内容(因为该源
派生自跨站数据),本规范修改了多个 [PERMISSIONS-POLICY] 算法,
使
fencedframe
Document
的
继承策略在计算时
不考虑其源是否与其嵌入者同源。
因此,某个特性只有在其嵌入者通过特殊值 * 允许列表显式
委托它时,才能在
fencedframe
内部启用。
考虑以上所有内容,对于固定权限策略行为导航,我们得到以下有趣影响:
-
如果一个特性存在于 有效启用 权限中,且其默认允许列表为 特殊值 *,并且在
fencedframe嵌入者上未提供 `Permissions-Policy` 标头,且allow属性为空,则fencedframe内部的导航 将成功,且生成的Document将被允许使用该特性(即该特性将被启用)。 -
如果一个特性存在于 有效启用 权限中,且其默认允许列表为
'self',并且在fencedframe嵌入者上未提供 `Permissions-Policy` 标头,且allow属性 为空,则fencedframe内部的导航会被阻止。注: 这是因为通常此特性只有在 子框架的
Document与其嵌入者同源时才会启用;本规范会避免对围栏框架执行该检查,因为fencedframe的Document的 源派生自跨站数据。因此,我们只是“失败关闭”。 -
如果一个特性存在于 有效启用 权限中,且其默认允许列表为
'self',并且fencedframe的allow属性包含该特性但没有允许列表,则根据allow属性一节中描述的规则, 该特性的默认 允许列表将为'src',其意在 表示由嵌入者提供的导航 URL;而在导航fencedframe时并不存在这样的 URL,因为导航 URL由围栏框架配置决定。该 导航将被阻止。 -
如果一个特性存在于 有效启用 权限中,且其默认允许列表为
'self',但fencedframe的 嵌入者提供的 `Permissions-Policy` 标头或allow属性将该特性的允许列表 设为特殊值 *,则fencedframe内部的导航将成功,且 生成的Document被允许使用该特性。 -
如果
fencedframe内部的导航本来会成功,但fencedframe内部导航上的响应携带了一个 `Permissions-Policy` 标头,该标头为 允许列表设置 "none",或为有效启用 权限中的某个特性设置了其他不兼容的源,该导航仍然成功,但fencedframe中的Document不会被允许使用该特性。注: 这是可以接受的,因为作出禁用某个特性决定的是
fencedframe的 内容自身,而不是其嵌入者环境。
下面一节中的补丁会“围栏化”适当的 [PERMISSIONS-POLICY] 和 [HTML] 算法,以实现上述说明性内容中描述的结果。
4.3.1. 定义
围栏
框架允许权限是 "private-aggregation"、
"shared-storage" 或 "shared-storage-select-url"。
4.3.2. 算法补丁
iframe
元素的 allow 属性一节重命名为“iframe
和 fencedframe 元素的 allow
属性”,并重写该节为:
iframe
和
fencedframe
元素分别具有 allow 属性
(iframe:
allow;
fencedframe:
allow),
其中包含一个ASCII 序列化策略指令。
属性中命名特性的允许列表可以为空;在这种情况下,该允许列表的默认
值为 "src",它表示 iframe 的
src
属性中 URL 的源,或 fencedframe 的围栏框架配置。
非空时,
iframe
的
allow
或
fencedframe
的
allow
属性会在构造
iframe
或
fencedframe
的
容器策略时,为每个受支持特性添加一个允许列表。
给定一个围栏可导航体容器(container)和 一个源(origin),此算法 返回一个新的权限策略。
-
令 fencedFrameConfig 为 container 的节点 document的活动浏览上下文的围栏框架配置 实例。
-
令 inheritedPolicy 为一个新的有序 映射。
-
如果 fencedFrameConfig 不是 null,且 fencedFrameConfig 的权限策略 行为为fixed,则:
-
否则:
-
-
如果 feature 匹配围栏框架允许 权限之一,则将 inheritedPolicy[feature] 设为给定 feature、 container 和 origin 运行为容器中某源处的特性定义继承策略的结果。
否则,将 inheritedPolicy[feature] 设为 "
Disabled"。
-
-
-
令 policy 为一个新的权限策略,其继承策略为 inheritedPolicy,且声明策略初始化为两个新的 有序映射。
-
返回 policy。
给定 null 或一个元素(container)、一个源(origin),以及一个默认值为 false 的可选布尔值 matchAll,此算法返回一个新的权限策略。
将第 1 步重写为:
将第 3 步重写为:
-
-
令 isInherited 为在 feature、container、 origin 和 matchAll 上运行为容器中某源处的特性定义继承策略的结果。
-
将 inherited policy[feature] 设为 isInherited。
-
给定 null、一个可导航体容器或围栏可导航体 容器(container)、一个 源(origin),以及一个响应 (response),此算法返回一个 新的权限策略。
将第 1 步重写为:
-
如果 container 是一个围栏可导航体容器,则令 policy 为给定 container 和 origin 运行 为围栏可导航体创建权限策略的结果。
否则,令 policy 为给定 container 和 origin 运行为可导航体创建权限策略的结果。
-
如果 element 不是
iframe元素,也不是fencedframe元素,则 返回一个空的策略指令。
-
给定 navigationParams 运行导航 请求的导航响应是否应被权限策略阻止?的结果为 "
Blocked"; -
给定 navigationParams 和 sourceSnapshotParams 运行导航 请求的导航响应是否应被沙盒化标志阻止?的结果为 "
Blocked";
注: 如果这些算法中的任意一个返回
"Blocked",则
fencedframe
中已有的 Document
不会继续保留;将加载错误页面。
给定一个导航参数(navigationParams),此算法
返回 "Blocked" 或
"Allowed":
-
令 navigable 为 navigationParams 的可导航体。
-
如果 navigable 不是一个围栏可导航体,则返回 "
Allowed"。 -
令 origin 为 navigationParams 的源。
-
令 effective permissions 为 navigable 的活动浏览上下文的 围栏框架配置 实例的有效启用 权限。
根据 pull request #84 中省略的工作,配置实例 此时尚未赋值给浏览上下文。我们应考虑把该实例存储在 navigationParams 中,并改为从这里引用它。
-
令 permissionsPolicy 为给定 navigable 的围栏 可导航体容器、origin 和 true 创建权限策略的结果。
注: 这几乎等同于在导航构造此待定导航的最终
Document时将会被创建的权限策略。区别在于,此算法就像在 iframe 上调用时一样, 会包含allow属性中指定的所有权限,即使该权限未在围栏框架配置的有效启用 权限中指定。我们现在创建它并对其运行 测试,因为这是确定导航是否会失败的适当时机,然后 将其丢弃。如果导航成功,它将被重新创建并无条件安装 到Document上。 但是,重新创建时不会包含任何未包含在有效启用 权限中的额外启用权限, 从而有效地将启用权限锁定为有效启用 权限中指定的内容。 -
令 inheritedPolicy 为 permissionsPolicy 的继承策略。
-
对于 effective permissions 中的每个 effective permission 执行:
-
如果 inheritedPolicy[effective permission] 为 "Disabled",则返回 "
Blocked"。
-
-
返回 "
Allowed"。
给定一个导航参数(navigationParams)和一个源快照参数
(sourceSnapshotParams),此算法返回 "Blocked" 或
"Allowed":
-
令 navigable 为 navigationParams 的可导航体。
-
如果 navigable 不是一个围栏可导航体,则返回 "
Allowed"。 -
令 effectiveSandboxingFlags 为 sourceSnapshotParams 的目标围栏框架 配置的有效沙盒化标志。
-
如果 navigationParams 的最终沙盒化标志集不是 effectiveSandboxingFlags 的子集,则返回 "
Blocked"。注: 这意味着最终沙盒化标志集不能限制一个在有效沙盒化 标志中尚未受限的特性,因为额外限制可被用作通信信道。到这个 时点,最终沙盒化标志集将已经被设为 至少与有效沙盒化 标志一样严格的内容。
-
否则,返回 "
Allowed"。
给定一个特性(feature)、null 或一个可导航体容器(container)、该容器中一个 document 的源(origin),以及一个默认值为 false 的可选布尔值 matchAll, 此算法返回该特性的继承策略。
将第 3 步重写为:
-
如果在 feature、 container 的节点 document、origin 和 matchAll 上执行特性是否在 document 中对某源启用?的结果为 "Disabled",则返回 "Disabled"。
注: 我们不必重写第 2 步;该步骤也
委托给同一个算法,以传入
matchAll 布尔值,因为第 2 步涉及检查
feature 是否已在
container 的节点 document中启用,而不是在 container 内部托管的
Document
中启用。
将第 7 步重写为:
-
如果 matchAll 为 false,feature 的默认允许列表为
'self',且 origin 与 container 的节点 document的 origin 同源,则返回"Enabled"。
给定一个特性(feature)、一个 Document
对象(document)、一个源
(origin),以及
一个默认值为 false 的可选布尔值 matchAll,如果
feature 应被视为禁用,则此算法返回 "Disabled",否则返回 "Enabled"。
将第 3 步重写为:
-
如果 feature 存在于 policy 的声明策略中,
将第 5 步重写为:
-
如果 node 的节点 document的浏览上下文的围栏框架配置 实例不是 null,则返回 node 的节点 document的 浏览上下文的围栏框架配置 实例的映射 url。
注: 这确保在使用围栏框架配置导航
fencedframe
(或使用映射到围栏
框架配置的 urn 导航
iframe)时,
可在
allow
属性中设置的 'src' 允许列表能够生效。
测试
- allow-attribute-src.https.html (实时 测试) (源代码)
- default-enabled-features-allow-all.https.html (实时 测试) (源代码)
- default-enabled-features-allow-none.https.html (实时 测试) (源代码)
- default-enabled-features-allow-self.https.html (实时 测试) (源代码)
- default-enabled-features-attribute-allow.https.html (实时 测试) (源代码)
- default-enabled-features-attribute-change.https.html (实时 测试) (源代码)
- default-enabled-features-attribute-disallow.https.html (实时 测试) (源代码)
- default-enabled-features-attribution-disabled.https.html (实时 测试) (源代码)
- default-enabled-features-subframe.https.html (实时 测试) (源代码)
- default-enabled-features-unset.https.html (实时 测试) (源代码)
- permission-api-denied-non-standard.https.html (实时 测试) (源代码)
- permission-api-denied.https.html (实时 测试) (源代码)
- permission-geolocation.https.html (实时 测试) (源代码)
- permission-notification.https.html (实时 测试) (源代码)
4.4. CSSOM View
[CSSOM-VIEW]
规范定义了 scrollIntoView()
方法,该方法会调用
将目标滚动到视图中算法。这不仅会滚动 Element
或
视口以使目标可见,而且还会在必要时滚动祖先,
以使目标可见,本质上会导致滚动“向上冒泡”。这意味着
在子可导航体或围栏可导航体中执行的
scrollIntoView()
可以被其嵌入者观察到,从而允许跨围栏框架
边界进行合谋。本节修补将目标滚动到视图中算法,以牺牲部分实用性
为代价来防止这种合谋。
-
如果 scrolling box 关联的
Element关联的Document的 节点可导航体的可遍历可导航体是一个围栏可导航体,或者如果 scrolling box 关联的视口关联的Document的 节点可导航体的可遍历可导航体是一个围栏可导航体,则令 这成为该算法的最后一个实例,并停止原本会继续执行的 任何进一步递归实例。
注: 这允许滚动“向上冒泡”到 围栏框架边界,但不跨越该边界。
4.5. Iframe credentialless
第一个引言小节是非规范性的。
[IFRAME-CREDENTIALLESS] 规范定义了一个新对象,即页面 credentialless nonce。从较高层面看,分区 nonce与页面 credentialless nonce具有相同 目的(对存储和网络进行分区)。但是,每个 围栏框架都有自己的唯一 nonce,而页面 credentialless nonce只有一个, 其作用域限定为可遍历可导航体的活动 window,并由所有 后代 credentialless iframe 共享。
在围栏框架和 credentialless iframe 同时存在于同一树中的情况下,子级的 nonce 始终优先于其父级的 nonce。例如:
-
如果 credentialless iframe 是围栏框架的子级,则页面 credentialless nonce将 用于为该 iframe 分区资源。
-
如果围栏框架是 credentialless iframe 的子级,则围栏框架的 分区 nonce将用于 分区资源。
除了资源分区之外,分区 nonce还用于 撤销围栏框架中的网络访问。将以下猴子补丁应用到 [IFRAME-CREDENTIALLESS] 规范。
添加以下算法:
在通过获取创建导航参数中,在第 18 步和第 19 步之间添加一个 新步骤,其内容为:
-
令 partitionNonce 为在 browsingContext 上运行计算有效 分区 nonce的结果,给定在 browsingContext 上计算导航的 credentialless 标志的结果,以及 null。
注: 我们在此处向计算有效 分区 nonce传入 null,是因为 我们希望源自围栏框架的导航获取使用与围栏框架自身相同的分区。 在导航获取完成并初始化 document 后,我们可以通过围栏框架配置实例的 分区 nonce访问正确的分区 nonce。
将第 19 步重新编号为第 20 步,并将第 20.2.4 步重写为:
6.9. 令 partitionNonce 为在 browsingContext 上计算有效 分区 nonce的结果,给定 navigationParams 的 credentialless,以及如果 navigationParams 的围栏框架配置实例为 null,则为 null,否则为 navigationParams 的围栏框架配置实例的分区 nonce。
4.6. WebRTC
[WEBRTC] 规范定义了“ECMAScript APIs
in WebIDL to allow media and generic
application data to be sent to and received from another browser or device implementing the
appropriate set of real-time protocols”。促进与对等方连接的接口是
RTCPeerConnection。
在围栏框架中不允许构造此接口,因此也不允许通过
WebRTC 连接到对等方。
RTCPeerConnection
constructor
算法,以添加新的第一步和
第二步,内容为:
-
如果 navigable 不是 null,且 navigable 的可遍历可导航体是一个围栏可导航体,则抛出一个
NotAllowedErrorDOMException。
5. 安全与隐私考虑
这些材料正在从我们的解释文档上游移植到本规范中,在此期间 你可以查阅以下资源: