链接点击分析和隐私

我们最近收到了关于我们所说的链接点击分析的问题,特别是关于禁用锚点元素 Ping 属性的内部设置。

默认隐私

WebKit 始终致力于实现默认隐私。举三个独特的此类努力为例——我们默认隔离第三方数据存储和 ServiceWorker,我们默认隔离 HTTP 缓存,并且我们的智能跟踪预防(ITP)功能在 Safari 中默认开启。据我们所知,市场上没有其他浏览器提供类似的保护。

然而,在某些情况下,用户希望获得更强的隐私保障,并愿意为此牺牲一些功能或网络兼容性。两个这样的例子是无痕浏览和内容拦截器。

让我们看看 Safari 和 WebKit 的隐私功能如何在链接点击分析中发挥作用。

什么是链接点击分析?

链接点击分析的目标是向网络服务器报告发生了导航链接点击,并且用户正在离开网页。这种审计可用于第一方网站分析以及第三方跨站跟踪。后者正是 ITP 的用武之地。

网站如何进行链接点击分析?

网站可以通过多种方式进行链接点击分析。我们今天看到使用的有:

  • 同步 XHR (XMLHttpRequest)。
  • 异步 XHR 或 Fetch,带延迟。
  • 第一方跳板跟踪。
  • Beacon API。
  • Ping 属性。

让我们详细了解这些技术。

同步 XHR

同步 XHR 是 XMLHttpRequest 的同步版本。此类同步调用通常会导致网络挂起,因为它们会阻塞网页,直到它等待服务器响应。因此,网络浏览器正在积极尝试移除该 API。

在链接点击分析的上下文中,一个愿意给用户带来不便的网站可能会做以下事情(请不要使用这项技术

window.addEventListener("unload", function(event) {
  let xhr = new XMLHttpRequest(),
      data = captureTrackingData(event);

  xhr.open("post", "/log", false); // 'false' implies synchronous.
  xhr.send(data);
});

上述代码在用户点击链接且当前网页卸载时触发。同步 XHR 会阻塞导航直到完成,这会显著延迟导航。对于用户而言,这被认为是糟糕的性能。

异步 XHR 或 Fetch,带延迟

另一种流行的链接点击分析方法是通过异步 XHR 或 Fetch,这主要是因为它们允许向第三方跟踪器发起跨站请求。

虽然这不会阻塞网页上的所有执行,但它会引入人为的导航延迟,用户会感到性能不佳。我们在此类链接点击分析脚本中看到过 100 到 350 毫秒的延迟,甚至有些在等待时会进行忙碌循环。以下是带有异步 XHR 的延迟导航示例:

const clickTime = 350; // Milliseconds.

theLink.addEventListener("click", function(event) {
  event.preventDefault(); // Cancel the user's link click.

  let xhr = new XMLHttpRequest(),
      data = captureTrackingData(event);

  xhr.open("post", "/log", true); // 'true' implies asynchronous.
  xhr.send(data);
  setTimeout(function() {
    window.location.href = theLink.getAttribute("href");
  }, clickTime); // Navigate properly after 350 ms.
});

第一方跳板跟踪

您可能还记得我们之前的博客文章中提到,ITP 2.0 会检测第一方跳板跟踪器,并将其归类为任何其他类型的跨站跟踪器。

假设用户在 social.example 网站上点击了一个 news.example 链接。他们不是直接导航到目的地 news.example,而是快速地通过 trackerOne.example 和 trackerTwo.example 导航,然后才到达 news.example。

social.example → trackerOne.example → trackerTwo.example → news.example

这是一种让 trackerOne 和 trackerTwo 进行链接点击分析的方式,而增加的加载时间再次对性能不利。

Beacon API

虽然并非专门为链接点击分析而构建,但 Beacon API 是一种在不影响用户体验的情况下发送任意分析和/或跟踪数据的方式。以下是 Beacon 如何用于链接点击分析的示例:

window.addEventListener("unload", function(event) {
  let data = captureTrackingData(event);
  navigator.sendBeacon("https://tracker.example/", data);
});

Beacon 请求保证在页面卸载前启动,但不会阻塞网页或延迟导航。

Ping 属性

Ping 是锚点元素上的一个属性,通常简称为链接。Ping 的目的就是链接点击分析,简单明了。以下是它的使用方式:

<a href="https://news.example" ping="https://tracker.example/going-to-news-example">Read the news</a>

上述对 tracker.example 的 Ping 请求不会阻塞或延迟导航到 news.example。

WebKit 能对此做什么?

如上所述,网站有多种方式记录或跟踪用户的点击。前三种——同步 XHR、带延迟的 Fetch 和第一方跳板跟踪——都会损害性能,并降低网络体验。后两种——Beacon 和 Ping——仍然记录点击,但不会损害性能。

仅仅关闭 Ping 属性或 Beacon API 并不能解决链接点击分析的隐私问题。相反,它会促使网站采用损害用户体验的跟踪技术。实际上,支持 Ping 与否的选择并非隐私问题,而是良好用户体验与糟糕用户体验之间的选择。

因此,我们的方法是让 ITP 阻止 cookie 并降级 referrer header(参见我们 ITP 2.0 博客文章中关于 Origin-Only Referrer 的部分),用于所有列出的链接点击分析技术,当请求发送到被归类为具有跨站跟踪能力的第三方域时。ITP 还会清理第一方跳板跟踪器的网站数据。

我们在这里做出的区分是,一般的链接点击分析与与个别用户绑定的第三方链接点击分析之间的区别。后者是 ITP 阻止的,也是我们认为默认开启的隐私保护功能的正确平衡点。

用户能对此做些什么?

对于希望完全阻止第三方链接点击分析的用户,WebKit 和 Safari 支持内容拦截器。此类加载阻止的效果可能包括阻止广告或第三方小部件。如果您想安装内容拦截器,请查看 App Store,您会找到大量选择。如果您是希望构建内容拦截器的开发人员,请参阅 Apple 开发者文档

关于隐藏功能标志的最后说明

作为其实现细节,WebKit 在 Apple 平台上利用了 User Defaults 机制。这些标志或配置数据并未在 Safari 的菜单或 Safari 设置中公开。相反,它们用于控制功能的内部运作,例如启用质量保证测试。

假设 WebKit 决定在 Apple 平台上彻底淘汰同步 XHR。这样的更改可能会放在 User Defaults 标志后面,以便工程师可以轻松评估报告的问题是否源于被淘汰的同步 XHR,还是其他原因。

直到最近,Safari 仍然支持一个内部的 User Defaults 标志来禁用对 Ping 属性的支持。我们从未打算将此标志作为客户设置公开。我们认为,如果禁用面向网络的功能并不能禁用或阻止该技术的目的,那么向用户提供禁用它的能力是错误的。相反,智能跟踪预防和内容拦截器为用户提供了不同级别的支持,以分类方式影响链接点击分析。