如何解决在Cloudfront错误页面上未调用Lambda @ Edge函数
我有一个Angular应用程序的静态文件通过Cloudfront放在S3存储桶中。我的Cloudfront发行版中设置了错误页面,因此仍呈现Angular的index.html。这意味着,如果我请求<cloudfront-distribution>.cloudfront.net/home-page
,而不是说它没有在S3存储桶上找到名为home-page
的文件,它仍将渲染angular应用程序,angular应用程序将处理该{{ 1}}路线。
我需要在应用服务器上包括一些安全标头,因此我设置了Lambda @ Edge函数以在查看器响应事件中注入这些标头(如此处https://aws.amazon.com/blogs/networking-and-content-delivery/adding-http-security-headers-using-lambdaedge-and-amazon-cloudfront/所述)。
Lambda @ Edge正在处理实际上与S3存储桶中的文件相对应的路由(如果我在S3存储桶的根文件夹中有一个名为/home-page
的文件,并且我请求image.png
,我看到了通过Lambda @ Edge函数注入的响应标头。问题是访问与S3存储桶中的文件不对应的路由时,如果我访问<cloudfront-distribution>.cloudfront.net/image.png
,S3将返回404 ,Cloudfront将处理404并根据错误页面配置进行相应的操作,即以200状态代码响应并呈现index.html文件。当发生这种情况时,我看不到我通过Lambda注入的任何标头@Edge函数,而我的Angular应用程序的所有其他脚本文件都有标题。
如何通过Lambda @ Edge函数使所有响应通过?
解决方法
在 Origin Response 上运行 Lambda@Edge 函数后它工作正常。但是,请不要忘记在进行此更改后在 CloudFront 上运行失效。它还可以节省资金,因为只有在将请求发送到 Origin 时才会执行 Lambda
,我刚刚经历了完全相同的情况。我发现 AWS 文档中的这个页面最有帮助:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-cloudfront-trigger-events.html
虽然 the current 的答案对于这个问题绝对是正确的,但我还有另一个限制可能有助于讨论:
- CloudFront 函数仅针对查看器请求/响应事件触发;与可以由 Origin 或 Viewer 事件触发的 Lambda@Edge 函数 相反。就我而言,我想继续使用 CloudFront 功能,因为它们更轻/更快/更便宜。
正如您所观察到的(并在 the docs 中调用),当源处出现错误时,不会触发查看器响应事件 - 包括当自定义错误页面返回为 200 时。
选项 #1 - 切换到源请求事件
如果您已经在使用 Lambda@Edge 并且不想更改任何内容,这可能是最简单的更改。
- 请记住,这发生在 CloudFront 中的任何缓存之前,因此不会再次调用缓存命中。因此可能不适用于所有用例。
- 但是,这也可能是一件好事,因为它的 lambda 执行次数更少,并且标头应包含在缓存中。
选项 #2 - 停止使用自定义错误响应
对我来说,我走这条路。我需要为 Viewer Request 事件创建第二个函数,该函数重写任何不是专门针对 s3 资源的请求,以便 React Router 路径返回我的 index.html。 (类似这样:https://stackoverflow.com/a/60012469/4413888)。最后,删除了我在 CloudFront 中现有的自定义错误响应。
- 是的,这是对每个资源请求执行的另一个函数,但在 about 1/6 the cost 的 lambda@edge 调用(免费层之后),我想我仍然领先。
- 从 s3 中发现实际 403/404 的好处——比如当用户尝试加载旧的 webpack 块和死链接时
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。