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

AWS S3+Cloudfront static website subdirectories not working

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

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

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

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

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

However, if you define a default root object, an end-user request for a subdirectory of your distribution does not return the default root object. For example, suppose index.html is your default root object and that CloudFront receives an end-user request for the install directory under your CloudFront distribution:

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

CloudFront does not return the default root object even if a copy of index.html appears in the install directory.

If you configure your distribution to allow all of the HTTP methods that CloudFront supports, the default root object applies to all methods. For example, if your default root object is index.php and you write your application to submit a POST request to the root of your domain (http://example.com), CloudFront sends the request to http://example.com/index.php.

The behavior of CloudFront default root objects is different from the behavior of Amazon S3 index documents. When you configure an Amazon S3 bucket as a website and specify the index document, Amazon S3 returns the index document even if a user requests a subdirectory in the bucket. (A copy of the index document must appear in every subdirectory.) For more information about configuring Amazon S3 buckets as websites and about index documents, see the Hosting Websites on Amazon S3 chapter in the Amazon Simple Storage Service Developer Guide.

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 设置:

谢谢

已修复,总结一下我所做的有两个解决方案:

  • 在 CloudFront 中添加 S3 URL 作为自定义来源代价是这会迫使我们为匿名流量打开 S3 存储桶.
  • 设置一个 Lambda@Edge 来翻译请求,代价是我们还要支付 Lambda 请求

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

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

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