Cloudflare Zaraz 的开源托管组件


最近决定把一些我觉得挺有意思的文章翻译一下,一是自己看,二是以后跟别人讲某个观点的时候不用逼别人看英文。当然肯定不是我自己翻译的而是 gpt 翻译的

原文:Open source Managed Components for Cloudflare Zaraz —— Yo'av Moshe

在2020年初,我们尝试思考是否有一种方法可以在不减慢网站速度、不降低安全性并且不牺牲用户隐私的情况下加载互联网上的第三方工具。晚上,在扫描了数以千计的网站后,我们的答案是“嗯,算是吧”。这似乎是可能的:许多类型的第三方工具仅仅是在浏览器中收集信息,然后将其发送到远程服务器。理论上,我们可以找出它们正在收集什么,然后只需高效地收集一次,并在服务器端将其发送到他们的服务器,模仿他们的数据模式。如果我们这样做,我们可以完全地避免在网站内加载他们的JavaScript代码。这意味着不再有恶意脚本的风险,不再有性能损失,隐私问题也会减少。

但答案并不是一个明确的“是!”因为我们意识到这将会非常复杂。我们调查了主要第三方脚本的网络请求,往往显得晦涩难懂。我们为自己设定了大量工作,研究工具所发出的网络请求,试图弄清楚它们在做什么——这个参数是什么?这个网络请求何时发送?这个值是如何散列的?我们如何以更安全、可靠和高效的方式实现相同的结果?我们的团队每天都在面临这些问题。

当我们加入Cloudflare时,一切的规模都发生了变化。突然之间,我们在成千上万的网站上,每秒为超过10,000个请求提供服务。用户每天都通过我们的Discord频道、社区论坛,有时甚至直接在Twitter上与我们交流。他们的消息通常会是这样的:“你好!你能支持X吗?”Cloudflare Zaraz上线时,其库中有大约30个工具,但这个市场非常庞大,新工具不断涌现。

改变我们的信任模式

在我之前关于Zaraz如何使用Cloudflare Workers的博客文章中,我包含了一些关于Zaraz中工具集成的编写方式的例子。通常,Zaraz中的“工具”是一个准备有效负载并发送它的函数。这个函数可以返回一个东西——clientJS,即浏览器稍后会执行的JavaScript代码。我们尽力做到这样,即工具不会使用clientJS,除非真的有必要,实际上大多数Zaraz构建的工具集成都没有使用clientJS

这运作得很好,只要我们是编写所有工具集成的人,客户信任我们会编写性能和安全的代码,并信任他们在尝试Zaraz时看到的结果。加入Cloudflare后,许多第三方工具供应商联系了我们,要求编写Zaraz集成。我们很快意识到我们的系统并没有强制执行速度和安全性——供应商可以简单地将他们旧的浏览器端JavaScript倒入我们的clientJS变量,然后说“我们有一个Cloudflare Zaraz集成!”,这完全不是我们的愿景。

我们希望第三方工具供应商能够编写他们自己的高效、安全的服务器端集成。我们希望使他们有可能以更好的方式重新构想他们的工具。我们还希望网站所有者能够了解他们网站上发生的事情,能够管理和控制它,并相信如果一个工具通过Zaraz运行,它必须是一个好的工具——这不是因为是谁编写的,而是因为它所构建的技术。我们意识到,为了实现这一点,我们需要一个新的定义第三方工具的格式。

引入Managed Components

我们开始重新思考如何编写第三方代码。今天,它是一个黑匣子——你通常会在你的网站上添加一个脚本,而你完全不知道它在做什么以及何时做。你无法正确阅读或分析缩小后的代码。你不知道它的行为是否与你在别处看到的一样。你不知道它何时会改变。如果你是网站所有者,你完全在黑暗中。

工具做很多不同的事情。简单的工具只是收集信息并将其发送到某处。通常,它们会设置一些cookies。有时,它们会在页面上安装一些事件监听器。基于小部件的工具可以真正操纵页面DOM,提供新的功能,比如社交媒体嵌入或聊天机器人。我们的新格式需要支持所有这些。

Managed Components是我们想象的在线第三方工具的未来。它为供应商提供了一个API,允许他们做比普通脚本更多的事情,包括将代码执行保持在浏览器之外。我们与供应商一起设计了这个格式,为供应商设计,同时考虑到用户的最大利益是每个人的长期最大利益。

从一开始,我们就构建Managed Components以使用基于权限的系统。我们希望提供比Zaraz今天更多的透明度。由于新API允许工具设置cookie、更改DOM或收集IP地址,所有这些能力都需要获得权限。安装在你网站上的第三方工具类似于在你的手机上安装应用程序——你会得到工具可以做什么和不能做什么的解释,并且可以在细粒度水平上允许或不允许功能。我们之前写过关于如何使用Zaraz不向Google Analytics发送IP地址,现在我们正在加倍努力朝这个方向发展。这是你的网站,这是你的决定。

每个Managed Component本质上是一个JavaScript模块。与今天不同的是,这个JavaScript代码不会被发送到浏览器。相反,它由一个Components Manager执行。这个管理器实现了组件使用的API。它调度来自浏览器的服务器端事件,为组件提供信息访问,同时保持它们的沙盒化和高效性。它处理缓存、存储等——所有这些都是为了让Managed Components能够实现其逻辑,而不必过多担心周围的环境。

一个示例分析Managed Component可能看起来像这样:

export default function (manager) {
  manager.addEventListener("pageview", ({ context, client }) => {
    fetch("https://example.com/collect", {
      method: "POST",
      data: {
        url: context.page.url.href,
        userAgent: client.device.userAgent,
      },
    });
  });
}

上述组件在发生页面浏览时会收到通知,然后它会创建一些包含访问者用户代理和页面URL的有效负载,并将其作为POST请求发送到供应商的服务器。这与今天的做法非常相似,只是这不需要在浏览器中运行任何代码。

但Managed Components不仅仅是做以前可能的事情,而是更好地做到,它们还提供了戏剧性的新的功能。看看我们如何公开服务器端端点的例子:

export default function (manager) {
  const api = manager.proxy("/api", "https://api.example.com");
  const assets = manager.serve("/assets", "assets");
  const ping = manager.route("/ping", (request) => new Response(204));
}

这三行代码是第三方可能性的完全转变。如果获得权限,它们可以代理一些内容,提供和公开它们自己的端点——所有这些都在运行网站的同一域下。如果一个工具需要进行一些处理,现在可以完全卸载浏览器,而不需强制浏览器与第三方服务器通信。

激动人心的新功能

每个第三方工具供应商都应该能够使用Managed Components API来构建其工具的更好版本。我们设计的API是全面的,对供应商的好处是巨大的:

  • 同一域: Managed Components可以从与网站本身相同的域提供资产。这允许更快和更安全的执行,因为浏览器只需信任和与一个服务器通信,而不是许多。这也可以降低供应商的成本,因为他们的带宽将会降低。
  • 网站范围的事件系统: Managed Components可以挂钩到网站用于跟踪事件的预先存在的事件系统。不仅不需要为你的工具提供浏览器端API,而且对用户来说更容易发送信息到你的工具,因为他们不需要学习你的方法。
  • 服务器逻辑: Managed Components可以在与网站同一域上提供服务器端逻辑。这包括代理不同的服务器,或添加生成动态响应的端点。这里的选项是无穷无尽的,这也可以减轻供应商服务器的负载。
  • 服务器端渲染的小部件和嵌入: 你有没有注意到,当你在网上加载一篇文章页面时,当一些YouTube或Twitter嵌入突然出现在段落之间时,内容会跳动?Managed Components提供了一个API用于注册服务器端渲染的小部件和嵌入。这意味着当页面到达浏览器时,它已经在其代码中包含了小部件。浏览器不需要与另一个服务器通信以获取一些推文信息或样式。它现在是页面的一部分,所以期待更好的CLS分数。
  • 可靠的跨平台事件: Managed Components可以订阅客户端事件,比如点击、滚动等,而无需担心浏览器或设备支持。不仅如此——这些相同的事件将在浏览器之外也能工作——但我们稍后再谈。
  • 预响应动作: Managed Components可以在网络响应甚至到达浏览器之前执行服务器端动作。那些动作可以访问响应对象,读取它或更改它。
  • 集成的同意管理器支持: Managed Components是可预测的和范围界定的。Component Manager知道它们需要什么,并可以预测运行它们需要哪种同意。

正确的选择:开源

当我们开始与供应商合作为他们的工具创建Managed Component时,我们听到一个反复出现的担忧——“有什么Components Managers?这是否仅对Cloudflare Zaraz客户有用?”虽然Cloudflare Zaraz确实是一个Components Manager,并且它有一个慷慨的免费计划,我们意识到我们需要考虑得更大。我们希望使Managed Components对互联网的每个人都可用,因为我们希望整个互联网变得更好。

今天,我们宣布的不仅仅是一个新格式。

WebCM是Managed Components API的参考实现。它是一个完整的Components Manager,我们将很快发布和维护。您将能够在构建Managed Component时将其用作SDK,即使您不是Cloudflare用户,也可以在生产中使用它来加载您网站上的Managed Components。WebCM作为一个代理工作——您将其放在您网站之前,并在必要时重写您的页面并添加几个端点。这使得WebCM 100%框架无关紧要——无论您的网站在后台使用Node.js、Python还是Ruby:只要您发送HTML,它都支持。

但这还不是全部!我们还将开源一些我们自己的Managed Components。我们将一些经典的Zaraz集成转换为Managed Components,它们将很快可供您使用和改进。您将能够获取我们的Google Analytics Managed Component,例如,并使用WebCM在您的网站上运行Google Analytics,100%服务器端,而无需Cloudflare。

技术领先的供应商已经加入

在互联网上革命性地改变第三方工具是我们只能与第三方供应商一起完成的事情。我们喜欢第三方工具,并且希望它们更加流行。这就是为什么我们与一些领先公司紧密合作,创建他们自己的Managed Components。这些新的Managed Components将Zaraz的能力扩展到远远超出现在的可能性,并为这些工具的新用户提供安全和可靠的入门体验。

DriftDrift帮助企业在最重要的时刻与客户建立联系。Drift的集成将让客户使用Drift强大的对话云——将对话营销、对话销售和对话服务整合到一个平台中——同时保持完全的沙盒化,并且无需进行第三方网络连接,从而提高用户的隐私和安全性。

CrazyEggCrazy Egg通过视觉热图、A/B测试、详细记录、调查等方式帮助客户改进他们的网站。网站所有者、Cloudflare和Crazy Egg都非常关心性能、安全性和隐私。Managed Components使Crazy Egg能够实现使用第三方JavaScript根本不可能的事情,这意味着我们的共同客户将获得最具性能和安全的网站优化工具之一。

我们也已经有客户渴望实现Managed Components:

Hopin Quote:

“我对Cloudflare的Zaraz能够将Drift的JS库移到Edge Worker并将其加载离开DOM印象深刻。由于页面加载时间的节省,我的工作更为有效。与积极寻求更好方法来增加大型MarTech堆栈的页面速度和加载时间的两家公司合作是一种乐趣。”– Sean Gowing,前端工程师,Hopin

如果您是第三方供应商,并希望加入这些技术领先的公司,请联系我们,我们会很乐意支持您编写自己的Managed Component。

Managed Components的下一步是什么

我们现在正在许多方面上开发Managed Components。在开发和维护WebCM、与供应商合作并将Managed Components集成到Cloudflare Zaraz中时,我们已经在思考未来的可能性。

我们看到未来有许多开源运行时存在于Managed Components中。也许您的基础设施不允许您使用WebCM?我们希望看到Managed Components运行时被创建为服务工作者、HTTP服务器、代理和框架插件。我们也在努力使Managed Components在移动应用中可用。我们正在努力允许在Cloudflare Zaraz上安装非官方的Managed Components。我们正在解决WWW的一个长期问题,还有很多事情要做。

我们很快将发布Managed Components的完整规格。我们也将开源WebCM,参考实现服务器,以及许多您可以自己使用的组件。如果这对您很有趣,请通过zaraz@cloudflare.com与我们联系,或加入我们的Discord