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 正文公开给源响应触发器。您可以通过将其设置为所需的值来生成静态内容主体,或者通过将值设置为空来删除函数内部的主体。如果您不更新函数中的正文字段,则源服务器返回的原始正文将返回给查看器。
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
这意味着未处理的错误导致没有响应触发触发。
但是,当自定义错误响应文档处理源错误时,源触发器会在回退请求上触发,包括错误文档成功呈现时的源响应,您可以在此处找到解决方案。
如果您将其实现为源响应触发器而不是查看器响应触发器,则您的代码将运行,因为在获取/index.html
(替代错误页面)时,源返回 200,这会调用源响应触发器——但查看器响应触发器仍然没有不开火。此行为似乎没有完整记录,但测试显示 Origin Request 和 Response 触发器在成功获取错误文档时分别触发,只要使用触发器配置了路径与错误文档匹配的缓存行为。
事实上,似乎 Origin Response 触发器对您的应用程序更有意义,因为它能够在响应进入缓存之前修改响应,并且添加的标头将与响应一起缓存 - 这应该会导致总体上减少了触发器实际需要触发的次数。
您可以将其添加为 Origin Response 触发器,等待分发返回到Deployed
,然后执行缓存失效/*
(这样您就不会提供任何没有添加标头的缓存页面),并且在失效完成后,删除查看器响应触发器。
旁白:我提交了一个功能请求,以支持在错误时触发响应触发器,但我不知道这是否是他们正在考虑添加的内容,显然我不是唯一一个,因为该功能已实现并发布,因为在修改后的答案中描述。