2022 年夏天,我的队友 Kailan 为 Fastly Compute 开发了 Rust 箱,实现了 Edge Side Includes (ESI) 模板语言的子集,并发表了一篇关于它。这篇文章很重要,不仅因为我们发布了一个有用的库,还因为它很好地说明了计算可以为我们带来什么:具有模块化功能的可编程边缘。现在 JavaScript 在 Compute 上普遍可用已有一年多了,我们是时候为 JavaScript 用户提供类似的解决方案了。 Fastly 的 JavaScript ESI 库现已在 npm 上提供,允许您向应用程序添加强大的 ESI 处理。
近十年来,Fastly 的 CDN 一直支持 Edge Side Includes (ESI),这是一种模板语言,通过解释 HTML 源代码中的特殊标签来工作。它围绕标签
index.html
<body> <esi:include src="./header.html" /> <main> Content </main> </body>
header.html
<header>Welcome to the web site</header>
输出
<header>Welcome to the web site</header>Content
当计算进入场景时,边缘景观主要在两个方面发生了变化:可编程性和模块化。
在我们对 Rust 的平台支持稳定后不久,我们发布了一个实现 ESI 的 Rust 包,并添加了可编程性。您现在可以使用代码配置如何构建其他后端请求以及如何处理响应片段。您甚至可以对并非来自后端服务器的文档执行 ESI 处理。这种可编程性将其与我们在 VCL 中提供的 ESI 支持区分开来,后者仅限于我们提供的固定功能集。
同时,这种方法是高度模块化的,使程序员可以选择在每个请求的基础上执行此 ESI 处理,并可以选择将处理与使用兼容数据类型的其他模块结合起来,并应用它们按照指定的任何顺序和/或逻辑条件。
与我们的 Rust 版本类似,我们希望这个 JavaScript 库是可编程的。 Fastly 的 JavaScript 支持始终包含 Fetch API 及其配套的 Streams API。 Streams API 的一项有用功能是 TransformStream 接口,它允许通过对象“输送”数据以应用转换,这对于 ESI 来说是完美的。通过将 ESI 处理器实现为 TransformStream 的实现,我们能够将其直接放入用 JavaScript 编写的快速计算应用程序中。
您可以通过以下方式进行流式传输:
<body> <esi:include src="./header.html" /> <main> Content </main> </body>
我们将其称为 EsiTransformStream 的转换直接应用于流,从而减轻了内存和性能问题。这意味着:
此外,这种设计是模块化的,使 EsiTransformStream 成为您可以与其他东西一起使用的另一个工具。例如,您可能希望对响应应用其他转换(例如压缩),并且可以通过任意数量的这些转换流传送响应,因为它是完全标准的接口。 如果您愿意,您甚至可以有条件地仅针对某些请求或响应启用 ESI,例如通过请求标头、路径或响应内容类型。
以下是实例化 EsiTransformStream 的方法:
<header>Welcome to the web site</header>
构造函数接受一个 URL 和一个 Headers 对象,并且可以选择接受一些选项作为第三个参数。如前所述,ESI 的主要功能是下载附加模板,以包含到结果流中。遇到
在最简单的情况下,您将仅使用配置对象的获取值。如果您不提供它,那么它会使用全局获取函数,但在计算中,您将需要它来指定一个后端,以供在包含模板时使用的获取(除非您使用动态后端功能)。上面的示例片段在调用全局获取之前分配名为 origin_0 的后端。
就是这样!通过这个简单的设置,您可以拥有一个服务 ESI 标签的后端和一个处理它们的计算应用程序。这是您可以运行的完整示例:
此实现提供了比我们过去提供的其他功能更多的 ESI 功能。
有时,
<body> <esi:include src="./header.html" /> <main> Content </main> </body>
如果 /templates/header.html 导致错误,ESI 处理器会默默地忽略该错误并替换整个
还可以通过使用
<header>Welcome to the web site</header>
ESI 处理器首先执行
需要注意的是,整个
ESI 还允许通过对变量执行运行时检查来进行条件执行。以下是此类检查的示例:
<header>Welcome to the web site</header>Content
当处理器遇到
处理器提供一组有限的变量,这些变量主要基于请求 cookie。在上面的示例中,检查名为“group”的 HTTP cookie 的值。我们的实现是基于ESI语言规范;请参阅它以了解更多详细信息。
此实现支持 ESI 语言规范的以下标签。
ESI 标签的属性支持 ESI 变量,
虽然功能集足以令人兴奋,但可编程的真正令人兴奋的部分是更多的事情是可能的。引入模板是 ESI 的主要用途,但这绝不是它能做的全部。这是一个例子。
假设您在文档中标记了一个时间戳,您希望在显示时将其表示为相对日期,例如“2 天前”。执行此操作的方法有很多,但为了获得最佳性能和内存影响,最好在流中执行查找/替换。对此 ESI 库进行编程实际上可以作为实现此目的的一个不错的选择。
我们可以使用特制的 ESI 标签定义要在后端文档中编码的时间戳,格式如下:
<body> <esi:include src="./header.html" /> <main> Content </main> </body>
例如,此代码片段可以代表太平洋时间 2024 年 1 月 1 日午夜:
<header>Welcome to the web site</header>
现在,设置 EsiTransformStream 以在看到该 URL 模式时提供合成替换文档:
<header>Welcome to the web site</header>Content
现在,当处理器遇到上面的示例片段时,它将发出类似于以下内容的结果(取决于您未来运行它的天数):
const transformedBody = resp.body.pipeThrough(esiTransformStream); return new Response( transformedBody, { status: resp.status, headers: resp.headers, }, );
由于后端文档可通过 Fastly 进行缓存,因此未来的请求可以从缓存 HIT 中受益,同时处理将继续显示更新的相对时间。
有关此示例的实例,请查看以下小提琴:
@fastly/esi 现已在 npm 上提供,可以添加到任何 JavaScript 程序中。当然,在 Fastly Compute 程序的边缘使用它,但事实上,只要您的环境支持 fetch API,它甚至可以在 Compute 之外工作。完整的源代码可在 GitHub 上获取。
甚至在创建 Fastly 帐户之前,就可以开始克隆上面的任何一个 Fiddle,并用您自己的来源测试它们。当您准备好在我们的全球网络上发布服务时,您可以注册 Compute 的免费试用版,然后立即开始使用 npm 上的 ESI 库。
通过计算,边缘是可编程和模块化的 - 选择并组合最适合您的解决方案,甚至构建您自己的解决方案。我们并不是唯一能够为计算提供此类模块的公司。任何人都可以为生态系统做出贡献并从中受益。并且,一如既往,在 Fastly 社区论坛上与我们见面,让我们知道您一直在构建什么!
以上是模块化边缘端包含 JavaScript 计算组件的详细内容。更多信息请关注PHP中文网其他相关文章!