共享存储空间和私有聚合实现快速入门

本文档是使用共享存储空间和私有汇总的快速入门指南。您需要了解这两个 API,因为共享存储空间会存储值,而不公开汇总会创建可汇总报告。

目标受众群体:广告技术平台和效果衡量服务提供商。

Shared Storage API

为防止跨网站跟踪,浏览器已经开始对所有形式的存储进行分区,包括本地存储、Cookie 等。不过,有些用例需要使用未分区的存储空间。Shared Storage API 可跨不同的顶级网站提供无限的写入权限,同时具有可保护隐私的读取权限。

共享存储空间仅限于上下文源(sharedStorage 的调用方)。

共享存储空间对每个来源都有容量限制,并且每个条目的字符数上限也不同。如果达到该限制,系统便不会再存储任何其他输入。“共享存储空间”说明中列出了数据存储限制。

调用共享存储空间

广告技术平台可以使用 JavaScript 或响应标头写入共享存储空间。从共享存储空间读取仅在名为 worklet 的隔离 JavaScript 环境中进行。

  • 使用 JavaScript 广告技术平台可以在 JavaScript 工作区之外执行特定的 Shared Storage 函数,例如设置、附加和删除值。不过,读取共享存储空间和执行私密汇总等函数必须通过 JavaScript 工作函数来完成。可在 JavaScript 工作区之外使用的方法可在拟议的 API Surface - 工作区之外中找到。

    您可以在建议的 API Surface - Worklet 中找到操作期间在 Worklet 中使用的方法。

  • 使用响应标头

    与 JavaScript 类似,只有特定函数(如设置、附加和删除共享存储空间中的值)可以使用响应标头完成。如需在响应标头中使用共享存储空间,请求标头中必须包含 Shared-Storage-Writable: ?1

    如需从客户端发起请求,请根据您选择的方法运行以下代码:

    • 使用 fetch()

      fetch("https://a.example/path/for/updates", {sharedStorageWritable: true});
      
    • 使用 iframeimg 标记

      <iframe src="https://a.example/path/for/updates" sharedstoragewritable></iframe>
      
    • 使用带有 iframeimg 标记的 IDL 属性

      let iframe = document.getElementById("my-iframe");
      iframe.sharedStorageWritable = true;
      iframe.src = "https://a.example/path/for/updates";
      

如需了解详情,请参阅共享存储空间:响应标头

写入共享存储空间

如需写入共享存储空间,请从 JavaScript Worklet 内部或外部调用 sharedStorage.set()。如果从 worklet 外部调用,数据将写入发起调用的浏览上下文的来源。如果从 worklet 内部调用,系统会将数据写入加载了 worklet 的浏览上下文的来源。设置的密钥的失效日期为上次更新后的 30 天。

ignoreIfPresent 字段为可选字段。如果存在且设置为 true,则如果键已存在,则不会更新该键。密钥到期时间会延长至 set() 调用后的 30 天,即使密钥未更新也是如此。

如果在同一页面加载期间使用相同的键多次访问共享存储空间,则该键的值会被覆盖。如果键需要保留之前的值,最好使用 sharedStorage.append()

  • 使用 JavaScript

    在 Worklet 之外:

    window.sharedStorage.set('myKey', 'myValue1', { ignoreIfPresent: true });
    // Shared Storage: {'myKey': 'myValue1'}
    window.sharedStorage.set('myKey', 'myValue2', { ignoreIfPresent: true });
    // Shared Storage: {'myKey': 'myValue1'}
    window.sharedStorage.set('myKey', 'myValue2', { ignoreIfPresent: false });
    // Shared Storage: {'myKey': 'myValue2'}
    

    同样,在 Worklet 内:

    sharedStorage.set('myKey', 'myValue1', { ignoreIfPresent: true });
    
  • 使用响应标头

    您还可以使用响应标头写入共享存储空间。为此,请在响应标头中使用 Shared-Storage-Write 以及以下命令:

    Shared-Storage-Write : set;key="myKey";value="myValue";ignore_if_present
    
    Shared-Storage-Write : set;key="myKey";value="myValue";ignore_if_present=?0
    

    如果有多个项,可以以英文逗号分隔,而且可以组合使用 setappenddeleteclear

    Shared-Storage-Write :
    set;key="hello";value="world";ignore_if_present, set;key="good";value="bye"
    

附加值

您可以使用附加方法将值附加到现有键。如果键不存在,调用 append() 会创建键并设置值。这可以使用 JavaScript 或响应标头来实现。

  • 使用 JavaScript

    如需更新现有键的值,请从 Worklet 内部或外部使用 sharedStorage.append()

    window.sharedStorage.append('myKey', 'myValue1');
    // Shared Storage: {'myKey': 'myValue1'}
    window.sharedStorage.append('myKey', 'myValue2');
    // Shared Storage: {'myKey': 'myValue1myValue2'}
    window.sharedStorage.append('anotherKey', 'hello');
    // Shared Storage: {'myKey': 'myValue1myValue2', 'anotherKey': 'hello'}
    

    如需在 worklet 中附加内容,请执行以下操作:

    sharedStorage.append('myKey', 'myValue1');
    
  • 使用响应标头

    与在共享存储空间中设置值类似,您可以在响应标头中使用 Shared-Storage-Write 传入键值对。

    Shared-Storage-Write : append;key="myKey";value="myValue2"
    

从共享存储空间读取

您只能在 worklet 中从共享存储空间读取数据。

await sharedStorage.get('mykey');

用于加载 Worklet 模块的浏览上下文的来源决定了系统会读取谁的共享存储空间。

从共享存储空间中删除

您可以使用 JavaScript 从工作区内外或通过使用响应标头与 delete() 搭配使用来从共享存储空间中执行删除操作。如需一次性删除所有键,请从任一键使用 clear()

  • 使用 JavaScript

    如需从 Worklet 外部删除共享存储空间中的内容,请执行以下操作:

    window.sharedStorage.delete('myKey');
    

    如需从 Worklet 内部从共享存储空间中删除,请执行以下操作:

    sharedStorage.delete('myKey');
    

    如需从 Worklet 外部一次性删除所有键,请运行以下命令:

    window.sharedStorage.clear();
    

    如需从 worklet 中一次性删除所有键,请执行以下操作:

    sharedStorage.clear();
    
  • 使用响应标头

    如需使用响应标头删除值,您还可以在响应标头中使用 Shared-Storage-Write 传递要删除的键。

    delete;key="myKey"
    

    如需使用响应标头删除所有键,请执行以下操作:

    clear;
    

上下文切换

共享存储空间数据会写入发起调用的浏览上下文的来源(例如 https://example.adtech.com)。

使用 <script> 标记加载第三方代码时,该代码会在嵌入器的浏览上下文中执行。因此,当第三方代码调用 sharedStorage.set() 时,数据会写入嵌入者的共享存储空间。当您在 iframe 中加载第三方代码时,该代码会收到一个新的浏览上下文,其来源是 iframe 的来源。因此,从 iframe 发出的 sharedStorage.set() 调用会将数据存储到 iframe 源的共享存储空间中。

第一方环境

如果第一方网页嵌入了调用 sharedStorage.set()sharedStorage.delete() 的第三方 JavaScript 代码,则键值对会存储在第一方环境中。

存储在嵌入了第三方 JavaScript 的第一方页面中的数据。

第三方环境

通过创建 iframe 并从 iframe 内的 JavaScript 代码中调用 set()delete(),您可以将键值对存储在广告技术平台或第三方上下文中。

存储在广告技术或第三方环境中的数据。

Private Aggregation API

如需衡量存储在共享存储空间中可汇总的数据,您可以使用 Private Aggregation API。

如需创建报告,请在 worklet 内使用存储分区和值调用 contributeToHistogram()。分桶由无符号的 128 位整数表示,该整数必须作为 BigInt 传入函数。该值为正整数。

为保护隐私,报告的载荷(包含存储分区和值)会在传输过程中加密,并且只能使用汇总服务进行解密和汇总。

浏览器还会限制网站对输出查询的贡献。具体而言,贡献预算会限制给定浏览器在给定时间范围内一个网站上所有存储分区中所有报告的总金额。如果超出当前预算,则不会生成报告。

privateAggregation.contributeToHistogram({
  bucket: BigInt(myBucket),
  value: parseInt(myBucketValue)
});

执行共享存储空间和专用聚合

您必须创建一个工作函数才能访问共享存储空间中的数据。为此,请使用 worklet 的网址调用 createWorklet()。默认情况下,将 createWorklet() 与共享存储空间搭配使用时,数据分区来源将是发起浏览上下文的来源,而不是 Worklet 脚本本身的来源。

如需更改默认行为,请在调用 createWorklet 时设置 dataOrigin 属性。

  • dataOrigin: "context-origin":(默认)数据存储在调用浏览上下文的来源的共享存储空间中。
  • dataOrigin: "script-origin":数据存储在工作区脚本源的共享存储空间中。请注意,您必须选择启用此模式,才能使用此模式。
sharedStorage.createWorklet(scriptUrl, {dataOrigin: "script-origin"});

如需选择启用,使用 "script-origin" 时,脚本端点必须使用标头 Shared-Storage-Cross-Origin-Worklet-Allowed 进行响应。请注意,应为跨源请求启用 CORS

Shared-Storage-Cross-Origin-Worklet-Allowed : ?1

使用跨源 iframe

需要 iframe 才能调用共享存储空间 Worklet。

在广告的 iframe 中,通过调用 addModule() 加载 worklet 模块。如需运行在 sharedStorageWorklet.js worklet 文件中注册的方法,请在同一广告 iframe JavaScript 中调用 sharedStorage.run()

const sharedStorageWorklet = await window.sharedStorage.createWorklet(
  'https://any-origin.example/modules/sharedStorageWorklet.js'
);
await sharedStorageWorklet.run('shared-storage-report', {
  data: { campaignId: '1234' },
});

在 Worklet 脚本中,您需要创建一个具有异步 run 方法的类,并通过 register 方法在广告的 iframe 中运行。在 sharedStorageWorklet.js 中:

class SharedStorageReportOperation {
  async run(data) {
    // Other code goes here.
    bucket = getBucket(...);
    value = getValue(...);
    privateAggregation.contributeToHistogram({
      bucket,
      value
    });
  }
}
register('shared-storage-report', SharedStorageReportOperation);

使用跨源请求

借助共享存储空间和专用聚合,无需跨源 iframe 即可创建跨源 Worklet。

第一方网页还可以调用对跨源 JavaScript 端点的 createWorklet() 调用。创建 Worklet 时,您需要将该 Worklet 的数据分区来源设置为脚本来源。

async function crossOriginCall() {
  const privateAggregationWorklet = await sharedStorage.createWorklet(
    'https://cross-origin.example/js/worklet.js',
    { dataOrigin: 'script-origin' }
  );
  await privateAggregationWorklet.run('pa-worklet');
}
crossOriginCall();

跨源 JavaScript 端点必须使用标头 Shared-Storage-Cross-Origin-Worklet-Allowed 进行响应,并注意为该请求启用了 CORS。

Shared-Storage-Cross-Origin-Worklet-Allowed : ?1

使用 createWorklet() 创建的工作流程将具有 selectURLrun()addModule()无法用于此目的。

class CrossOriginWorklet {
  async run(data){
    // Other code goes here.
    bucket = getBucket(...);
    value = getValue(...);
    privateAggregation.contributeToHistogram({
      bucket,
      value
    });
  }
}

后续步骤

以下页面介绍了 Shared Storage API 和 Private Aggregation API 的重要方面。

熟悉这些 API 后,您就可以开始收集报告了。这些报告会以 JSON 格式在请求正文中作为 POST 请求发送到以下端点。

  • 调试报告 - context-origin/.well-known/private-aggregation/debug/report-shared-storage
  • 报告 - context-origin/.well-known/private-aggregation/report-shared-storage

收集报告后,您可以使用本地测试工具进行测试,也可以设置适用于汇总服务的可信执行环境来获取汇总报告。

欢迎分享反馈

您可以在 GitHub 上分享对 API 和文档的反馈。