AWS S3+Cloudfront 静态网站子目录不起作用

Posted

技术标签:

【中文标题】AWS S3+Cloudfront 静态网站子目录不起作用【英文标题】:AWS S3+Cloudfront static website subdirectories not working 【发布时间】:2021-05-21 22:31:02 【问题描述】:

我正在尝试使用自定义域将静态网站设置到 S3 中,并使用 CloudFront 处理 HTTPS。

问题是根路径可以正常工作,但子路径不能正常工作。

显然,这与我在两个地方都配置为 index.html 的默认根对象有关。

example.com -> example.com/index.html - 工作正常 example.com/about/ -> example.com/about/index.html - 因 NoSuchKey 错误而失败

有趣的是,如果我打开对 S3 存储桶的读取访问权限并使用 S3 URL,它完全可以正常工作。

有一个 AWS 文档页面,他们在其中讨论了这个问题:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DefaultRootObject.html,但他们甚至没有说解决方案,或者至少我没能找到它。

但是,如果您定义默认根对象,最终用户请求 您的发行版的子目录不返回默认根目录 目的。例如,假设 index.html 是您的默认根对象 并且 CloudFront 收到最终用户的安装请求 CloudFront 分配下的目录:

http://d111111abcdef8.cloudfront.net/install/

CloudFront 不会返回默认根对象,即使是 index.html 出现在安装目录中。

如果您将分发配置为允许所有 HTTP 方法 CloudFront 支持的,默认根对象适用于所有 方法。例如,如果您的默认根对象是 index.php 并且您 编写您的应用程序以向您的根目录提交 POST 请求 域 (http://example.com),CloudFront 将请求发送到 http://example.com/index.php.

CloudFront 默认根对象的行为不同于 Amazon S3 索引文档的行为。当您配置 Amazon S3 存储桶作为网站并指定索引文档,Amazon S3 返回 即使用户请求了索引文档中的子目录 桶。 (索引文件的副本必须出现在每个 子目录。)有关配置 Amazon S3 的更多信息 存储桶作为网站和关于索引文档,请参阅托管 Amazon Simple Storage Service 中的 Amazon S3 上的网站一章 开发者指南。

S3 存储桶策略:


    "Version": "2012-10-17",
    "Statement": [
        
            "Sid": "AllowCloudFrontAccess",
            "Effect": "Allow",
            "Principal": 
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXXXX"
            ,
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::example.com/*"
        
    ]

CloudFront 设置:

谢谢

【问题讨论】:

开启 S3 静态 Web 托管,并在 CloudFront 中使用 s3 网站 URL。 我已经有了,事实上,根路径工作正常,错误出在子文件夹中,不知何故 CloudFront 只能在根路径中到达 index.html,但在子文件夹中没有。 你是对的,我发现here 的响应,结果证明在 CloudFront 中将 URL 设置为自定义源可以正常工作,但我不完全确定它是最佳选择,但在最少的作品,谢谢 【参考方案1】:

这个问题已经解决了,总结一下我所做的有两个解决方案:

S3 URL 添加为 CloudFront 中的自定义源折衷方案是这会迫使我们为匿名流量打开 S3 存储桶。 设置将翻译请求的 Lambda@Edge折衷方案是我们也将支付 Lambda 请求

所以每个人都必须决定更适合的选项,在我的情况下,预计流量会非常低,所以我选择了第二个选项。

我留下一些有用的链接,以防其他人遇到同样的问题:

有用的 Reddit 线程 here AWS Lambda@Edge+CloudFront 解释 AWS here 修复了我遇到的 Lambda 错误here 所有设置过程解释here

【讨论】:

“将 S3 URL 添加为 CloudFront 中的自定义源,权衡是这会迫使我们为匿名流量打开 S3 存储桶。” 这可以通过例如S3 的 HTTP 基本身份验证密码或侦听特定标头值。也许有一种更智能的方法可以使用一些 AWS 内部 mojo 来限制访问,但这两个是我所知道的最流行的解决方案。 我在 s3 上托管了一个公共静态网站,所以只需放置存储桶端点 URL 就可以了。在此之前,我使用存储桶名称作为来源。感谢您的洞察力!

以上是关于AWS S3+Cloudfront 静态网站子目录不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AWS S3 网站 CloudFront 中设置别名重定向?

Terraform无法使用静态S3网站端点创建CloudFront的原点

AWS CloudFront 重定向到 S3 存储桶

没有 S3 存储桶的 AWS Cloudfront CORS 标头

使用 SSL 的 AWS 静态网站未正确路由

具有 Route 53 域的 AWS S3 网站,需要通过 CloudFront 进行 https