订阅以接收新文章的通知:

通过 WebCM 构建和使用托管组件

2022-08-03

8 分钟阅读时间
这篇博文也有 English繁體中文版本。

托管组件能够颠覆第三方工具与网站的集成方式。两个月前,我们宣布对 Cloudflare Zaraz 背后最具创新性的一部分技术进行开源,使其可供所有人在线访问和使用。自那以后,我们一直竭力确保为代码配套良好的文档,并且所有片段都富有乐趣、易于使用。在本文中,我准备展示托管组件可以怎样立即帮助您管理网站或构建第三方工具。但是,在深入探索之前,我们先谈谈过去的情况吧。

Building and using Managed Components with WebCM

第三方脚本对您的网站构成威胁

几十年来,如果要将分析工具添加到您的站点,无论是聊天小部件、转换像素还是其他任何种类的工具,都需要包含一个外部脚本。这通常意味着将类似于以下内容的代码添加到网站中:

好好想一想,这其实是个糟糕的想法。这样做不仅要求浏览器连接到_另一个_服务器,获取并执行_更多_ JavaScript 代码,还得完全放弃对网站的控制权。这个脚本到底有多值得信任?又如何确保脚本的服务器没有被入侵,或者将来绝不会被入侵?在之前的博客文章中,我们展示了包含一个脚本通常会导致更多网络调用,从而独占浏览器,拖慢一切。但这些脚本最糟糕的地方在于,它们完全不受限制:浏览器中运行的 JavaScript 代码可能会劫持用户,盗取其凭据或信用卡信息,使用其设备来进行加密货币采矿,操控您的网站,泄露 PII 等。由于这些脚本中的代码通常缩小了,基本上不可能加以阅读并搞清楚其细节。

<script src=”https://example.com/script.js”></script>

托管组件改变了这一局面。它们就像手机里的应用一样,是围绕一种权限系统而构建的。您可以决定是否允许某个组件连接到远程服务器,是否允许它执行使用 Cookie、运行代码或将小部件注入页面中等操作。不同于缩小的外部脚本,它是一种提升透明度的框架。网站所有者可以将权限切换为开或关,未获权限的托管组件无法访问相关 API。

但托管组件所能做的远不止为当前系统配上权限,它们还提供了前所未有的功能:建立服务器端连接,缓存信息,使用键值存储,操控响应之后将其交由浏览器处理等。此功能的核心在于,能够在浏览器外部执行代码。将浏览器解放出来,不再运行过去在浏览器中执行的代码,意味着您的网站运行速度可以提高大约 40%,同时还可以在您的工具供应商受到入侵时缩小攻击面。

借助新的托管组件 API,所有这一切都可以实现。我们与供应商一起设计了这个 API,确保您可以用其编写任何工具,同时将性能、安全性和隐私作为首要任务。托管组件的核心只是一个 JavaScript 模块,因此每个 JavaScript 开发人员在构建托管组件时应该会感到如鱼得水。请查看我们上一篇博客文章中的两个示例,了解其实际情况,或者查看我们已经在 GitHub 上开源的一些托管组件

WebCM 是开源组件管理器

工具加载了 <script> Tag 标记之后,其代码由浏览器执行。由于托管组件不在浏览器中运行,其代码需要在别处执行。这就是组件管理器。我们有意围绕托管组件设计了 API,就是为了不绑定到特定组件管理器,事实上,如今已经诞生了两个管理器:Cloudflare Zaraz 和 WebCM。

WebCM 是基于 Web 的组件管理器,是我们对组件管理器的开源参考实现。如果您运行一个网站,即使您不是 Cloudflare 用户,也可以立即使用 WebCM 在您的网站上运行托管组件。如果您想创建托管组件,则可以像使用 SDK 一样使用它。

过去几个月来,我们一直在帮助供应商编写其自己的托管组件,并会继续这一工作。我们将 WebCM 开源,以确保托管组件成为整个 Web 界的技术。所有人都应该能够使用 WebCM 加载和创建托管组件。下面就来看一看怎么使用吧!

WebCM 5 分钟入门

WebCM 入门其实比想象的简单。因为 WebCM 工作原理类似于代理,无论您的网站是如何构建的,都可以使用它。在新的文件夹中,创建简单的 HTML 文件并将其命名为 index.html

在相同文件夹中启动一个 HTTP 服务器来提供此文件:

<!DOCTYPE html>
<html lang=”en”>
  <head>
	<meta charset="UTF-8">
	<title>My Website</title>
  </head>
  <body>
    	<h1>WebCM test website</h1>  
  </body>
</html>

您可以使用 Node.js:

您可以使用 Python:

npx http-server -p 8000

或将在 http://localhost:8000/index.html 上提供我们的 HTML 文件的其他任何语言。

python3 -m http.server

接下来,为 WebCM 创建配置文件。在新目录中,创建名为 webcm.config.ts 的文件。

我们来详细考察一下这个配置文件:

export default {
  components: [
    {
      name: 'demo',
      permissions: [
        'access_client_kv',
        'provide_server_functionality',
        'provide_widget',
        'serve_static_files',
        'client_network_requests',
      ],
    },
  ],
  target: 'http://127.0.0.1:8000',
  hostname: 'localhost',
  trackPath: '/webcm/track',
  ecommerceEventsPath: '/webcm/ecommerce',
  clientEventsPath: '/webcm/system',
  port: 8080
}
  • components 是一个数组,列出了您想加载的所有托管组件。目前,我们将加载 demo 组件。请注意,我们只需要指定 “demo”,WebCM 就会从 NPM 获取它。其他托管组件也可从 NPM 获取,您也可以安装其他来源的组件。对于每个组件,我们会定义为其提供的 permissions。您可以在规范中阅读有关权限的更多信息。如果我们不对组件授予必需的权限就添加该组件,WebCM 会提醒我们。

  • target 是源 HTTP 服务器运行的位置。在上一步,我们将其设置为在端口 8000 上运行。

  • port 是 WebCM 提供我们的网站时所采用的端口。

  • hostname 是 WebCM 将绑定到的主机。

  • trackPathclientEventsPathecommerceEventsPath 是 WebCM 用于将事件从浏览器发送到其后端的路径。我们可以暂时不改动这些路径,后面再看看其用法。

!注意:下一部分需要 Node 版本 17 或更高版本

使 HTTP 服务器保持运行的同时,在与 webcm.config.ts 相同的目录中,运行 npx webcm。Node 将获取并启动 WebCM,然后 WebCM 将读取配置。首先,它将获取所需组件以将其放入 components 文件夹中。完成后,它会启动另一个服务器来代理您的源。

如果您立即在浏览器中打开 http://localhost:8080/index.html,您会看到 http://localhost:8000/index.html 中所显示的相同页面。虽然这些页面可能相似,但端口 8080 上运行的页面才运行着我们的 demo 托管组件。移动鼠标并在页面中单击应该会导致在 WebCM 终端打印消息,显示组件已加载且正在接收数据。您还会注意到,页面现在显示了简单的天气小部件,即附加到您页面的托管组件小部件。获取天气信息时,浏览器无需联系任何额外服务器,WebCM 可以缓存该信息,确保快速提供该信息。最后,如果您转至 http://localhost:8080/webcm/demo/cheese,就会看到该组件在提供一块奶酪的静态图片。此示例展示了在您允许的情况下,托管组件如何在服务器上公开新端点。

顾名思义,demo 组件就只是一个演示。我们使用它来展示并测试托管组件 API。要是我们想将真正的托管组件添加到站点该怎么办?Google Analytics 被互联网上超过半数的网站使用,因此我们看一下如何编辑 webcm.config.ts 文件来加载它。

在以上示例中,我们只是将 demo 组件替换为 Google Analytics 托管组件。请注意,该组件运行所需的权限少得多,因为它在 100% 的服务器端运行。别忘了将 UA-XXXXXX 替换为真正的 Google Universal Analytics(版本 3)帐户标识符。

export default {
  components: [
    {
      name: 'demo',
      permissions: [
        'access_client_kv',
        'provide_server_functionality',
        'provide_widget',
        'serve_static_files',
        'client_network_requests',
      ],
    },
    {
      name: 'google-analytics',
      settings: { 'tid': 'UA-XXXXXX' },
      permissions: [
        'access_client_kv',
      ],
    },
  ],
  target: 'http://127.0.0.1:8000',
  hostname: 'localhost',
  trackPath: '/webcm/track',
  ecommerceEventsPath: '/webcm/ecommerce',
  clientEventsPath: '/webcm/system',
  port: 8080
}

重新运行“npx webcm”将立即获取 Google Analytics 托管组件并使用您提供的设置运行它。如果您现在转至代理网站,则不会看到任何变化。但如果转至 Google Analytics 仪表板,则会逐渐看到“实时”视图上显示的页面浏览量。WebCM 加载了该组件,且正在将服务器端信息发送到 Google Analytics。

您可以试用其他许多组件,我们还在不断添加更多组件。请查看 NPMGitHub 上的托管组件组织,了解完整列表。

构建您自己的托管组件

托管组件并不是您可以使用的工具的封闭库。如前所述,我们正在逐渐对 GitHub 上我们库中的更多工具开源。如果您认为我们的组件表现怪异,请向我们提交问题,甚至可以提交 PR。托管组件可以惠及所有人。过去几个月来,Discord 和 Cloudflare 社区论坛上的 Cloudflare Zaraz 社区对于积极报告问题十分有用,因此我们很高兴为其提供一个选项,进一步了解 Cloudflare Zaraz 背后的内幕。

能改进现有托管组件固然是好,但我们认为更重要的是,您现在也可以构建自己的托管组件了。如果您是第三方工具供应商,您可以通过这种方式创建工具的安全高效版本,方便客户轻松发现和采用您的工具。如果您是网站开发人员,您可能想对托管组件进行一些改动,看看可以轻松从浏览器中移除哪些内容,从而提高性能。

我们来看一个非常简单的例子,创建一个托管组件来侦听我们网站上的每个页面浏览。运行 npm init managed-component(位于 WebCM 创建的 components 目录中),create-managed-component 将引导您完成搭建组件文件的过程。首先,我们的组件不会使用任何特殊权限,因此您可以选择“无”。

完成向导后,可以打开 src/index.ts 文件。默认情况下,组件会将侦听器添加到所有页面浏览:

现在来编辑注释行,以便每次发生页面浏览时都能看到。请注意,我们还为 settings 加了前缀 _ ,因为我们暂时不使用它:

import { ComponentSettings, Manager } from '@managed-components/types'

export default async function (manager: Manager, settings: ComponentSettings) {
  manager.addEventListener('pageview', event => {
    // do the things
  })
}

进行这些更改后,每次网站上的页面被浏览时,组件都会打印当前 URL。在尝试之前,我们需要构建组件。在组件所处的文件夹中,运行 npm i && npm run build。然后,使用组件的命名空间,将其添加到 webcm.config.ts 文件并重启 WebCM:

import { ComponentSettings, Manager } from '@managed-components/types'

export default async function (manager: Manager, _settings: ComponentSettings) {
  manager.addEventListener('pageview', event => {
    console.log(`New pageview at ${event.client.url}`)
  })
}

这是一个非常简单的组件,但它可以展示构建之前仅在浏览器中可用的功能有多么容易。您可以轻松扩展组件:使用 fetch(位于 console.log 语句旁边)并在站点上每次发生页面浏览时向您自己的分析仓库发送信息。阅读用于创建小部件侦听单击存储 Cookie使用缓存等用途的所有其他托管组件 API。这些 API 允许您构建达到前所未有丰富程度的工具。

export default {
  components: [
    {
      name: 'demo',
      permissions: [
        'access_client_kv',
        'provide_server_functionality',
        'provide_widget',
        'serve_static_files',
        'client_network_requests',
      ],
    },
    {
      name: 'google-analytics',
      settings: { 'tid': 'UA-123456' },
      permissions: [
        'access_client_kv',
      ],
    },
    {
      name: 'your-component-namespace',
      settings: {},
      permissions: [],
    },
  ],
  target: 'http://127.0.0.1:8000',
  hostname: 'localhost',
  trackPath: '/webcm/track',
  ecommerceEventsPath: '/webcm/ecommerce',
  clientEventsPath: '/webcm/system',
  port: 8080
}

工具采用托管组件的形式会更好

我们开始开发托管组件时,很多人都感到不解:工具供应商有什么动力去构建托管组件?在过去几个月,我们发现,供应商常常热衷于托管组件的理由跟我们一样:能够安全地使用其工具,且能够以简化方式将其工具集成到网站中。客户特别在乎这几点,所以采用托管组件时,客户更有可能尝试您的技术。供应商还将获得巨大的可发现性优势,因为其工具可以集成到 Cloudflare Zaraz 仪表板中,公开给上万个启用 Zaraz 的网站。很多主流供应商向我们表达了构建托管组件的意向,我们也竭尽所能,积极支持他们完成这个过程。如果贵公司有意向构建托管组件,请联系我们。我们坚信托管组件能够改变在线使用第三方工具的方式。要让这些工具更快速、安全、私密,这仅仅是开端。我们将与用户和供应商合作,持续不断地改进托管组件的功能,惠及万维网的所有用户。要开始构建您的托管组件,请前往 managedcomponents.dev 并开始构建。我们的团队随时为您效劳,请访问 managedcomponents@cloudflare.com 获取相关服务。

我们保护整个企业网络,帮助客户高效构建互联网规模的应用程序,加速任何网站或互联网应用程序抵御 DDoS 攻击,防止黑客入侵,并能协助您实现 Zero Trust 的过程

从任何设备访问 1.1.1.1,以开始使用我们的免费应用程序,帮助您更快、更安全地访问互联网。要进一步了解我们帮助构建更美好互联网的使命,请从这里开始。如果您正在寻找新的职业方向,请查看我们的空缺职位
ZarazManaged ComponentsOpen Source

在 X 上关注

Yo'av Moshe|@yoavmoshe
Cloudflare|@cloudflare

相关帖子

2024年10月22日 13:00

Is this thing on? Using OpenBMC and ACPI power states for reliable server boot

Cloudflare’s global fleet benefits from being managed by open source firmware for the Baseboard Management Controller (BMC), OpenBMC. This has come with various challenges, some of which we discuss here with an explanation of how the open source nature of the firmware for the BMC enabled us to fix the issues and maintain a more stable fleet....