Cloudfront 错误页面上未调用 Lambda@Edge 函数

Gui*_*ral 10 amazon-s3 amazon-web-services amazon-cloudfront angular aws-lambda-edge

我有一个 Angular 应用程序的静态文件通过 Cloudfront 在 S3 存储桶上提供。我的 Cloudfront 发行版设置了错误页面,因此它仍然呈现 Angular 的 index.html。这意味着,如果我请求<cloudfront-distribution>.cloudfront.net/home-page,而不是说它没有找到home-page在 S3 存储桶上命名的文件,它仍然会渲染角度应用程序,并且角度应用程序将处理该/home-page路由。

我需要在应用程序服务器上包含一些安全标头,因此我设置了 Lambda@Edge 函数以将这些标头注入查看器响应事件(如此处所述https://aws.amazon.com/blogs/networking-and-content -delivery/adding-http-security-headers-using-lambdaedge-and-amazon-cloudfront/)。

Lambda@Edge 适用于实际对应于 S3 存储桶中的文件的路由(如果我image.png在 S3 存储桶的根文件夹上调用了一个文件,并且我请求<cloudfront-distribution>.cloudfront.net/image.png,我会看到通过 Lambda@ 注入的响应标头Edge 函数。问题是当访问与 S3 存储桶中的文件不对应的路由时。如果我访问<cloudfront-distribution>.cloudfront.net/home-page,S3 将返回 404,Cloudfront 将处理 404 并根据错误页面配置进行操作,即响应使用 200 状态代码并渲染 index.html 文件。当发生这种情况时,我看不到通过 Lambda@Edge 函数注入的任何标头,而我的 Angular 应用程序的所有其他脚本文件都有标头。

如何使所有响应都通过 Lambda@Edge 函数?

phi*_*our 5

我刚刚经历过同样的情况。我发现 AWS 文档中的此页面最有帮助:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-cloudfront-trigger-events.html

虽然当前的答案对于这个问题来说绝对是正确的,但我还有另一个可能有助于讨论的限制:

  • CloudFront 函数仅针对查看者请求/响应事件触发;与可由 Origin 或 Viewer 事件触发的Lambda@Edge 函数相反。就我而言,我想继续使用 CloudFront 功能,因为它们更轻/更快/更便宜。

正如您观察到的(并在文档中调用的),当源头出现错误时,包括当自定义错误页面作为 200 返回时,不会触发查看器响应事件。

选项 #1 - 切换到原始请求事件

如果您已经在使用 Lambda@Edge 并且不想更改任何内容,这可能是最简单的更改。

  • 请记住,这发生在 CloudFront 中的任何缓存之前,因此不会因缓存命中而再次调用。因此可能不适用于所有用例。
  • 但是,这也可能是一件好事,因为 lambda 执行次数较少,并且标头应包含在缓存中。

选项 #2 - 停止使用自定义错误响应

对于我来说,我走了这条路。我需要为Viewer Request事件创建第二个函数,该函数重写任何不是专门针对 s3 资源的请求,以便 React Router 路径返回我的 index.html。(类似这样的: https: //stackoverflow.com/a/60012469/4413888)。最后,删除了 CloudFront 中现有的自定义错误响应。

  • 是的,这是在每个资源请求上执行的另一个函数,但大约是 lambda@edge 调用成本的 1/6(在免费套餐之后),我认为我仍然领先。
  • 受益于从 s3 发现实际的 403/404s - 就像当用户尝试加载旧的 webpack 块和死链接时


小智 0

在 Origin Response 上运行 Lambda@Edge Function 后,它工作正常。但是,请勿忘记在进行此更改后在 CloudFront 上运行失效。此外,它还可以节省资金,因为 Lambda 仅在请求发送到 Origin 时才会执行