使用 Lambda@Edge 的单页应用程序

Single Page Application with Lambda@Edge

所以我有一个由 AWS Cloudfront 从 AWS S3 提供的 SPA。我配置了以下错误页面行为:

404: Not Found -> /index.html HTTP 代码 200

这需要能够处理 client-side 上的路由。

现在我有一个 Lambda@Edge 函数,它由 Cloudfront 中的 viewer-response 事件触发并设置一些自定义 headers,如 HSTS 和 X-Frame。该函数正在被调用,并按预期在除实际 /index.html 之外的所有资源上工作。我倾向于认为这是因为它是由 Cloudfront 中的上述错误页面行为处理的,因为 html 的实际 GET 请求是由 Cloudfront 中的错误页面配置处理的。

解决这个问题的实用方法是什么?

我不确定为什么重定向没有触发 lambda 函数。有什么方法可以实现与 lambda@edge 中的错误页面配置相同的逻辑吗?

更新: 服务行为已更改。

https://aws.amazon.com/about-aws/whats-new/2017/12/lambda-at-edge-now-allows-you-to-customize-error-responses-from-your-origin/

下面的答案在发布时是正确的,但不再适用。原始错误现在按预期触发 Lambda@Edge 函数 在原始响应触发器(但不是查看器响应触发器)。

请注意,您可以在原始响应触发器中生成自定义响应body,但您无权以编程方式访问read 原始回复 body return 来自来源,如果有的话。你可以替换它,或者保持原样——不管它是什么。这是因为 Lambda@Edge 源响应触发器不会等待 之后触发 CloudFront 从源接收到整个响应——它们似乎会在源完成后立即触发 return将完整、有效的响应 header 返回给 CloudFront。

When you’re working with the HTTP response, note that Lambda@Edge does not expose the HTML body that is returned by the origin server to the origin-response trigger. You can generate a static content body by setting it to the desired value, or remove the body inside the function by setting the value to be empty. If you don’t update the body field in your function, the original body returned by the origin server is returned back to viewer.

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-updating-http-responses.html

重要提醒: 每当您在 CloudFront 上测试更改时,请记住您的更改往往比您预期的更早开始工作——在分发状态变回 Deployed,但您可能需要执行缓存失效以使您的更改完全生效并可见。失效应该包括浏览器实际请求的路径,而不是从源请求的路径(如果不同),或者 /* 使所有内容无效。查看来自 CloudFront 的响应时,如果有 Age: 响应 header,您正在查看缓存的响应。还要记住,错误使用一组不同的计时器来缓存响应。这些与缓存行为中的 TTL 值分开配置。请参阅我对 Amazon CloudFront Latency 的回答以了解如何更改错误缓存最小 TTL 的说明,该 TTL 默认为 5 分钟并且通常不遵守 Cache-Control headers。这是一种保护措施,可防止过多的错误到达您的来源(或触发您的 Lambda 函数),但如果您不知道其影响,则会在测试和故障排除期间造成混淆。


(原回答如下)

CloudFront doesn't execute Lambda functions for origin response and viewer response events if the origin returns HTTP status code 400 or higher.

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html

这意味着 未处理 错误导致无响应触发触发。

但是,当自定义错误响应文档处理原始错误时,原始触发器会在回退请求上触发,如果错误文档呈现成功,则包括原始响应,您可以在此处找到解决方案.

如果您将代码实现为原始响应触发器而不是查看器响应触发器,您的代码将 运行,因为在获取 /index.html(替代错误页面)时,原始 return s 200,调用 Origin Response 触发器——但 Viewer Response 触发器仍然没有触发。这种行为似乎没有被完整记录,但测试显示 Origin Request 和 Response 触发器在成功获取错误文档时分别触发,只要缓存行为与错误文档匹配的路径配置了触发器。

事实上,Origin Response 触发器似乎对您的应用程序更有意义,因为它将能够在 进入缓存之前 修改响应,并且添加的 header 将与响应一起缓存 - 这应该会导致触发器实际需要触发的次数总体减少。

你可以将它添加为 Origin Response 触发器,等待分发到 return 到 Deployed,然后为 /* 做一个缓存失效(这样你就不会为未添加 header 的缓存页面提供服务),并在失效完成后删除查看器响应触发器。

旁白:我提交了一个功能请求,以支持在出现错误时触发响应触发器但我不知道他们是否正在考虑添加此功能 显然我不是唯一一个,因为该功能已实现并发布,如修订后的答案中所述。