如何在嵌入器与 <iframe> 之间进行通信

当第三方代码被嵌入到 <iframe> 中时,<iframe> 和嵌入方可以自由地相互发送消息,将请求数据写入客户端的共享存储中。嵌入方可以向 <iframe> 发送请求,使用 Window.postMessage() 以通过跨文档通信通道将数据写入其自身的第三方存储中。第三方也可以通过发送 postMessage() 请求与嵌入方进行通信。
在 <iframe> 中,你可以监听来自嵌入方的 message 事件。当嵌入方使用 postMessage() 向 <iframe> 发送消息时,<iframe> 可以接收这些数据并将其存储在自身的客户端共享存储中。相反,<iframe> 也可以发送一条消息,嵌入方可以监听这条消息,并通过将数据写入其共享存储来做出响应。
如何在嵌入方与 <fencedframe> 之间进行通信
围栏框架(Fenced frame)旨在用于诸如通过受保护的受众 API 和 WindowSharedStorage.selectURL() 选择并展示定向广告等场景。页面上的 <fencedframe> 与 <fencedframe> 外部的其他页面之间的通信是故意受到限制的,但存在一种嵌入方与共享存储 worklet 之间的通信方法——FencedFrameConfig.setSharedStorageContext()。
备注:
在同一个 <fencedframe> 树结构中,允许各框架之间进行通信。例如,根 <fencedframe> 可以向其自己树结构中的子 <iframe> 发送消息,而子 <iframe> 也可以向父 <fencedframe> 发送消息。
让我们来看一个更复杂的例子,使用 selectURL 输出门操作(gate operation)来在 <fencedframe> 中渲染广告。

在这个例子中,发布商(Publisher)请求第三方内容提供商(Content Provider)在页面上渲染一些内容(Content)。使用 WindowSharedStorage.selectURL() 选择的内容将在 <fencedframe> 中渲染,并且该内容包含一个来自衡量服务提供商(Measurement)的 <iframe>。请注意,发布商可以代表任何嵌入第三方 <fencedframe> 的实体。同样,衡量服务提供商代表在任何不同第三方的 <fencedframe> 中运行的任何嵌套第三方代码。
为了将数据传递到 <fencedframe> 中以便在共享存储 worklet 中使用,嵌入方可以在 FencedFrameConfig 中设置数据。该值将在共享存储 worklet 内部作为 WorkletSharedStorage.context 提供。此数据在 worklet 之外不可用,并且只能在共享存储 worklet 提供的安全和私密环境中访问。

当 selectURL() 调用返回 FencedFrameConfig 时,框架嵌入方可以通过调用 setSharedStorageContext(data) 传递数据:
const fencedFrameConfig = await window.sharedStorage.selectURL(
"creative-rotation",
urls,
{
// …
resolveToConfig: true,
},
);
fencedFrameConfig.setSharedStorageContext("some-data");
// 导航至配置所指定的围栏框架。
document.getElementById("my-fenced-frame").config = fencedFrameConfig;
必须在将预期的 <fencedframe> 元素接收者的 config 属性设置为 fencedFrameConfig 之前,在 fencedFrameConfig 上调用 setSharedStorageContext(data),因为这会触发框架的导航。
在共享存储 worklet 内部,可以访问 WorkletSharedStorage.context 来检索该数据:
class ReportingOperation {
async run() {
sharedStorage.set("some-data-from-embedder", sharedStorage.context);
}
}
register("send-report", ReportingOperation);