针对查看器请求和查看器响应的单个 Lambda@Edge 函数调用

chr*_*vdb 1 amazon-web-services amazon-cloudfront aws-lambda-edge

我目前有两个 Lambda@Edge 函数:

  • language-redirect:根据查看器请求调用,返回 302 或将请求传递到 CloudFront
  • HSTS:在查看器响应时调用,添加响应标头

目前的流量为:

viewer request -> language-redirect

if 302 -> viewer response
if not 302 -> pass on to CloudFront -> HSTS -> viewer response
Run Code Online (Sandbox Code Playgroud)

是否可以将这两个功能组合到一个函数(组合)中,每个查看器请求仅调用一次?

viewer request -> combined

if 302 -> viewer response
if not 302 -> pass on to CloudFront -> combined -> viewer response
Run Code Online (Sandbox Code Playgroud)

目标是同一函数被调用一次,而不是同一函数被调用两次。

Mic*_*bot 7

CloudFront 的 Lambda@Edge 增强功能中有 4 个不同的触发事件。它们与缓存的交互以粗体显示,稍后变得很重要:

  • 查看器请求 - 在请求到达时检查缓存之前,对每个请求触发;自发生成的响应不会被缓存
  • 源请求 - 仅在请求到达源之前缓存未命中时触发;如果此触发器生成响应,则不会向源发送任何 HTTP 请求,并且响应将存储在缓存中(如果可缓存)
  • 原始响应 - 仅在缓存未命中时触发,当响应从原始返回时,在检查响应的可缓存性并将其存储在缓存中之前;如果此触发器修改了响应,则修改后的响应将存储在缓存中(如果可缓存)
  • 查看器响应 - 在响应返回给查看器之前立即触发,无论缓存命中还是未命中;对此触发器所做的响应的任何修改都不会被缓存

正确编写一个 Lambda 函数以了解它在事务周期内的何处被触发,可以在这些点的任意组合处触发 - 但由于这些事件都发生在不同的时间,因此不可能处理多个事件一次调用触发函数即可发生事件。

但是,请注意上面粗体显示的要点。在许多情况下,您可以通过使用源端触发器来显着减少触发器调用的数量。如上所述,使用这些触发器会导致触发器的响应可缓存 - 因此,当您的重定向触发器触发时,如果它生成重定向,则可以缓存该重定向,并且下一个请求不需要在以下位置调用触发器:全部。同样,将 HSTS 标头添加到源响应触发器中的可缓存响应意味着未来的缓存命中将返回带有 HSTS 标头的修改后的响应,而无需触发触发器。


更新:2021 年,CloudFront(终于!)推出了一项名为响应标头策略 的新功能,它允许您将静态 HTTP 响应标头配置为 CloudFront 发行版的一部分。这允许添加静态响应标头,例如 HSTS(如原始问题中提到的),而无需使用 Lambda@Edge 或 CloudFront Functions。