注册归因源

本文解释了如何在使用 Attribution Reporting API 时注册归因源。

基本方法

归因源的形式是您想要衡量其交互的内容中的链接、图像或脚本(例如,它们可能是您想要衡量转换的广告)。当发生特定的用户交互时,这些会使浏览器将源数据存储在私有的本地缓存中(仅浏览器可访问)。不同的归因源类型以不同的方式注册并表示交互 — 它们被区分为:

  • 导航源:当发生导航时,例如用户点击链接或使用键盘激活链接,或者由于 Window.open() 调用而发生导航时,浏览器会存储源数据。有关示例,请参阅基于导航的归因源
  • 事件源:当事件触发时,浏览器会存储源数据。有关示例,请参阅基于事件的归因源

在这两种情况下,注册源以及检索和存储源数据在幕后发生的过程是相同的:

  1. 当用户与归因源交互时,它会在向衡量交互的服务器(通常是广告商的服务器)发出的请求中发送一个 Attribution-Reporting-Eligible 头,这表明该响应有资格注册源。例如:

    http
    Attribution-Reporting-Eligible: navigation-source
    
  2. 当服务器收到包含 Attribution-Reporting-Eligible 头的请求时,它可以在响应中包含一个 Attribution-Reporting-Register-Source 头以完成源注册。其值是一个 JSON 字符串,提供浏览器应存储的有关发生交互的归因源的信息。此头中包含的信息还决定了浏览器将生成哪种类型的报告:

    • 以下示例将导致在将触发器与源匹配时生成事件级报告

      js
      res.set(
        "Attribution-Reporting-Register-Source",
        JSON.stringify({
          source_event_id: "412444888111012",
          destination: "https://advertiser.example",
          trigger_data: [0, 1, 2, 3, 4],
          trigger_data_matching: "exact",
          expiry: "604800",
          priority: "100",
          debug_key: "122939999",
          event_report_window: "86400",
        }),
      );
      

      在此上下文中,唯一必填的字段是 destination,它指定了预计发生触发器的 1-3 个站点。这些用于在与触发器交互时将归因触发器与源匹配。上面指定的其他字段执行以下操作:

      • "source_event_id": 一个字符串,表示归因源的 ID,当与归因源交互时,可用于将其映射到其他信息,或在报告端点聚合信息(有关端点信息,请参阅生成报告 > 基本过程)。
      • "trigger_data": 一个 32 位无符号整数数组,表示描述可能与此源匹配的不同触发事件的数据。例如,“用户将商品添加到购物车”或“用户订阅邮件列表”可能是触发器站点发生的行为,它们可能与此源匹配并指示广告商试图衡量的某种转换。这些必须与触发器中指定的 "trigger_data" 匹配,才能进行事件级归因。

        注意:用于表示每个事件的值以及数组中元素的数量完全是任意的,由您作为开发者定义。数组可能包含未使用的值,但必须在数组中存在值,以便浏览器在注册触发器时将其归因于来源。

      • "trigger_data_matching": 一个字符串,指定如何将触发器的 "trigger_data" 与源的 "trigger_data" 匹配。"exact" 是您几乎总是会使用的值,它匹配精确值。
      • "expiry": 一个字符串,表示归因源的过期时间(以秒为单位),在此之后它将不再活跃(即,后续触发器将无法归因于此源)。
      • "priority": 一个字符串,表示归因源的优先级值。有关更多信息,请参阅报告优先级和限制
      • "debug_key": 一个以 10 为基数的 64 位无符号整数,表示调试密钥。如果您想在关联的归因报告旁边生成调试报告,请设置此项。
      • "event_report_window": 一个字符串,表示一个时间(以秒为单位),在此之后,后续触发器将不再归因于此源,以用于生成事件级报告。

      有关此头中所有可用字段的详细说明,请参阅 Attribution-Reporting-Register-Source

    • 要使浏览器在触发器与源匹配时生成摘要报告,您需要除了生成事件级报告所需的字段外,**额外**包含一些字段。

      js
      res.set(
        "Attribution-Reporting-Register-Source",
        JSON.stringify({
          source_event_id: "412444888111012",
          destination: "https://advertiser.example",
          trigger_data: [0, 1, 2, 3, 4],
          trigger_data_matching: "exact",
          expiry: "604800",
          priority: "100",
          debug_key: "122939999",
          event_report_window: "86400",
      
          aggregation_keys: {
            campaignCounts: "0x159",
            geoValue: "0x5",
          },
          aggregatable_report_window: "86400",
        }),
      );
      

      此示例中的附加字段是:

      • "aggregation_keys": 一个对象,包含用户提供的密钥,表示要聚合报告值的不同数据点。
      • "aggregatable_report_window": 一个字符串,表示触发数据不再包含在生成的聚合报告中的时间(以秒为单位)。

      同样,有关此头中所有可用字段的详细说明,请参阅 Attribution-Reporting-Register-Source

  3. 成功注册源后,浏览器会将其提供的源数据存储在其私有本地缓存中。

导航源对于衡量与链接的交互非常有用——例如,用户可能会在发布商页面上看到广告,然后点击它导航到广告商页面,在那里有望发生转换。

可以注册几种不同类型的基于导航的归因源(例如,点击广告)——基于 HTML 的(使用 attributionsrc 属性)和基于 Window.open() 调用的(使用 attributionsrc 窗口功能)。

基于 HTML 的导航源

要注册基于导航的归因源,您可以将 attributionsrc 属性添加到相应的 <a> 元素中,该属性指定注册请求将发送到何处。

如果将属性值留空,注册请求将发送到链接到的位置。也可以在值中指定一个或多个附加 URL 以发送注册请求;有关详细信息,请参阅在 attributionsrc 中指定 URL

attributionsrc 可以声明性地添加:

html
<a href="https://shop.example" attributionsrc target="_blank">
  Click to visit our shop
</a>

或通过 HTMLAnchorElement.attributionSrc 属性添加:

js
const aElem = document.querySelector("a");
aElem.attributionSrc = "";

在这种情况下,当用户点击链接并且浏览器收到响应时,交互发生,导致浏览器存储与基于导航的归因源关联的源数据(如 Attribution-Reporting-Register-Source 响应头中提供)。

基于 Window.open() 的导航源

您还可以将 attributionsrc 功能关键字添加到 Window.open() 调用的 features 属性中。在此示例中,我们将其作为 click 事件触发的响应运行:

js
elem.addEventListener("click", () => {
  window.open("https://shop.example", "_blank", "attributionsrc");
});

在这种情况下,当调用 Window.open() 并且浏览器收到响应时,交互发生,浏览器存储源数据。

注意: 当设置像上面示例中的 click 事件时,建议将其设置在预期点击的控件上,例如 <button><a> 元素。这在语义上更有意义,并且对屏幕阅读器和键盘用户来说都更易于访问。

注意: 要通过 open() 注册归因源,必须在用户交互的五秒内使用瞬时激活(即,在用户交互事件处理程序(例如 click)内部)调用它。

基于事件的归因源

基于事件的归因源使浏览器在某种事件触发时存储源数据,例如 <img><script> 元素(它们像我们上面看到的 <a> 元素一样使用 attributionsrc 属性)的 load 事件,或者您在 JavaScript 中设置的自定义事件。

基于 HTML 的事件源

基于 HTML 的事件源可用于衡量发布商页面首次加载时的交互——或者更准确地说,当 <img><script> 加载时。要通过 HTML 注册基于事件的归因源,您可以将 attributionsrc 属性添加到相应的元素——<img><script>

如果将属性值留空,注册请求将发送到所请求资源所在的服务器。也可以在值中指定一个或多个附加 URL 以发送注册请求;有关详细信息,请参阅在 attributionsrc 中指定 URL

我们来看一个 <img> 元素示例:

html
<img src="advertising-image.png" attributionsrc />

您也可以通过 HTMLImageElement.attributionSrc 属性实现这一点:

js
const imgElem = document.querySelector("img");
imgElem.attributionSrc = "";

当浏览器收到包含图像文件的响应(即,当 load 事件发生时)时,浏览器会存储归因源数据。请记住,用户不一定能够完全感知图像——它可能是一个 1x1 的透明跟踪像素,仅用于归因报告。

一个 <script> 示例可能如下所示:

html
<script src="advertising-script.js" attributionsrc></script>

或通过 HTMLScriptElement.attributionSrc 属性:

js
const scriptElem = document.querySelector("script");
scriptElem.attributionSrc = "";

在这种情况下,当浏览器收到包含脚本的响应时,交互发生,浏览器存储源数据。

基于 JavaScript 的事件源

基于脚本的归因源比基于 HTML 的归因源更通用。您可以设置脚本以根据适合您应用程序的任何请求发起一个有资格注册归因源的请求。这是一种灵活的方法,当您想要响应自定义交互(例如,点击自定义元素或提交表单)存储源数据时非常有用。

要设置基于脚本的归因源,您可以选择:

  • 发送包含 attributionReporting 选项的 fetch() 请求

    js
    const attributionReporting = {
      eventSourceEligible: true,
      triggerEligible: false,
    };
    
    // Optionally set keepalive to ensure the request outlives the page
    function triggerSourceInteraction() {
      fetch("https://shop.example/endpoint", {
        keepalive: true,
        attributionReporting,
      });
    }
    
    // Associate the interaction trigger with whatever
    // event makes sense for your code (does not have to be a
    // DOM event/user interaction)
    elem.addEventListener("click", triggerSourceInteraction);
    
  • 发送 XMLHttpRequest,并在请求对象上调用 setAttributionReporting()

    js
    const attributionReporting = {
      eventSourceEligible: true,
      triggerEligible: false,
    };
    
    function triggerSourceInteraction() {
      const req = new XMLHttpRequest();
      req.open("GET", "https://shop.example/endpoint");
      // Check availability of setAttributionReporting() before calling
      if (typeof req.setAttributionReporting === "function") {
        req.setAttributionReporting(attributionReporting);
        req.send();
      } else {
        throw new Error("Attribution reporting not available");
        // Include recovery code here as appropriate
      }
    }
    
    // Associate the interaction trigger with whatever
    // event makes sense for your code (does not have to be a
    // DOM event/user interaction)
    elem.addEventListener("click", triggerSourceInteraction);
    

在这种情况下,当浏览器收到来自 fetch 请求的响应时,交互发生,浏览器存储源数据。

注意: 请求可以是任何资源。它不需要与 Attribution Reporting API 直接相关,可以是 JSON、纯文本、图像 blob 或其他任何对您的应用程序有意义的请求。

在 attributionsrc 中指定 URL

到目前为止,在我们看到的所有示例中,attributionsrc 属性/功能或 attributionSrc 属性都留空,取空字符串值。如果持有请求资源的服务器与您还希望处理注册的服务器是同一个服务器,即接收 Attribution-Reporting-Eligible 头并响应 Attribution-Reporting-Register-Source 头,则此做法是可行的。

但是,所请求的资源可能不在您控制的服务器上,或者您只是想在不同的服务器上处理归因源的注册。在这种情况下,您可以将一个或多个 URL 指定为 attributionsrc 的值。当资源请求发生时,除了资源源之外,Attribution-Reporting-Eligible 头将被发送到 attributionsrc 中指定的 URL;这些 URL 随后可以响应 Attribution-Reporting-Register-Source 以注册源。

例如,对于 <a> 元素,您可以在 attributionsrc 属性中声明 URL:

html
<a
  href="https://shop.example"
  attributionsrc="https://a.example/register-source">
  Click to visit our shop
</a>

或在 JavaScript 中通过 attributionSrc 属性:

js
// encode the URLs in case they contain special characters
// such as '=' that would be improperly parsed.
const encodedUrlA = encodeURIComponent("https://a.example/register-source");
const encodedUrlB = encodeURIComponent("https://b.example/register-source");

const aElem = document.querySelector("a");
aElem.attributionSrc = `${encodedUrlA} ${encodedUrlB}`;

对于 Window.open() 调用,不同的 URL 必须在 windowFeatures 参数中列为多个单独的 attributionsrc 功能,用逗号或空格分隔:

js
// encode the URLs in case they contain special characters
// such as '=' that would be improperly parsed.
const encodedUrlA = encodeURIComponent("https://a.example/register-source");
const encodedUrlB = encodeURIComponent("https://b.example/register-source");

elem.addEventListener("click", () => {
  window.open(
    "https://ourshop.example",
    "_blank",
    `attributionsrc=${encodedUrlA},attributionsrc=${encodedUrlB}`,
  );
});

注意:指定多个 URL 意味着可以在同一功能上注册多个归因源。例如,您可能正在尝试衡量不同广告系列的成功,这涉及生成关于不同数据的不同报告。

另见