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

app*_*lim 2 amazon-cloudfront aws-lambda aws-lambda-edge

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

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

这是在客户端处理路由所必需的。

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

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

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

Mic*_*bot 5

update:服务的行为已更改。

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 函数。

请注意,您可以在 Origin Response 触发器中生成自定义响应正文,但您无法通过编程访问读取从源返回的原始响应正文(如果有)。你可以更换它,或者保持原样——不管它是什么。这是因为 Lambda@Edge 源响应触发器CloudFront 收到来自源的整个响应不会等待触发——它们似乎在源完成将完整、有效的响应标头返回给 CloudFront 后立即触发。

当您使用 HTTP 响应时,请注意 Lambda@Edge 不会将源服务器返回的 HTML 正文公开给源响应触发器。您可以通过将其设置为所需的值来生成静态内容主体,或者通过将值设置为空来移除函数内部的主体。如果您不更新函数中的 body 字段,则源服务器返回的原始正文将返回给查看器。

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

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


(原答案如下)

如果源返回 HTTP 状态代码 400 或更高,CloudFront 不会为源响应和查看器响应事件执行 Lambda 函数。

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

这意味着未处理的错误会导致没有响应触发触发。

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

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

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

您可以将其添加为 Origin Response 触发器,等待分发返回到Deployed,然后对其进行缓存失效/*(这样您就不会提供任何未添加标头的缓存页面),并在失效完成后,删除查看器响应触发器。

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