使用 S3、CloudFront 和源路径的静态网站托管的子文件夹重定向问题

Posted

技术标签:

【中文标题】使用 S3、CloudFront 和源路径的静态网站托管的子文件夹重定向问题【英文标题】:Subfolder redirect issue with static website hosting using S3, CloudFront and Origin Path 【发布时间】:2016-05-27 10:37:59 【问题描述】:

我在使用 Amazon S3 和 Cloudfront 设置静态网站托管时遇到了一些困难。

我们有许多网站,我们希望使用 Amazon S3 + Cloudfront 将它们用作静态网站,并且我们希望将它们全部托管在一个 S3 存储桶中。

初始设置非常简单,但如果在 URL 中省略尾部斜杠,我们会遇到子文件夹重定向问题。

示例,从存储桶中设置单个网站:

网站 1 的存储桶内容:

s3://bucket-name/websites/website1/index.html

s3://bucket-name/websites/website1/about/index.html

我已为此存储桶启用静态网站托管,默认文档设置为“index.html”

我已经创建了一个 Cloudfront Web 分发来为这个单一网站提供服务,默认根对象设置为“index.html”。

分发有一个自定义来源,指向静态网站 url 'bucket-name.s3-website-us-east-1.amazonaws.com',来源路径设置为'/websites/website1'

当导航到分发 url 'http://example.cloudfront.net' 时,它会正确地提供来自 's3://bucket-name/websites/website1/index.html' 的 'index.html' 文档

当导航到“http://example.cloudfront.net/about/”时,它还可以正确地提供来自“s3://bucket-name/websites/website1/about/index.html”的“index.html”文档

但是,如果我省略尾随斜杠,如“http://example.cloudfront.net/about”,S3 会将我重定向到“http://example.cloudfront.net/websites/website1/about/”,因为我将源路径设置为“/websites/website1”,Cloudfront 将从“s3”请求 index.html: //bucket-name/websites/website1/about/websites/website1/about/index.html' 不存在。

我在这里遗漏了什么吗?这是仅使用 Cloudfront 和 S3 的不可能设置吗?

【问题讨论】:

我认为您需要为您的发行版添加多个来源(每个文件夹一个) @KhalidT。是的,这正是我尝试设置的方式,这只是我在子文件夹的 URL 中省略斜杠时遇到的重定向问题 由于 S3 是基于对象的存储,它不区分文件和文件夹(它们都是对象)。因此,我认为省略斜杠可能会导致这种行为 我正在为同样的问题而苦苦挣扎,我正在与 AWS Support 取得联系,但到目前为止,他们建议的解决方案并没有给出太多帮助。我设法通过省略存储桶中的前缀而不在 CloudFront 中设置源路径来解决此问题。基本上,这意味着每个网站一个存储桶,管理起来有点麻烦。我仍在尝试开发一个允许多个网站在一个存储桶中的解决方案,但我不抱希望。同时,单一网站/桶的方法是一种可行的解决方法,结合一些脚本来管理桶的创建和删除。 如果您分析网络流量,您会看到发生了什么,如果您想了解手头的问题。 CF 将接受您的 /about 请求并附加原始路径:/websites/website1/about。 S3 将响应 302 和 Location 标头:/websites/website1/about/。然后,客户端使用 /websites/website1/about/ 调用 CF,CF 将再次附加原始路径,使最终的 S3 调用 /websites/website1//websites/website1/about/ -> 404(或 403)。问题是 CF 和 S3 的行为与他们被告知的行为相同,只是它们的行为不兼容。 【参考方案1】:

我最终通过使用 S3 存储桶的路由规则解决了这个问题

https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html

问题是由于省略尾部斜杠导致的重定向导致原始路径被附加到完整的 S3 存储桶路径(“example.cloudfront.net/about”重定向到“example.cloudfront.net/websites/website1/ website/website1/about/" 因为路径无效而失败)

下面的路由规则通过触发错误的路径模式前缀并将前缀从请求中剥离后重定向回 Cloudfront 分配来解决此问题,即(“example.cloudfront.net/about”重定向到“example.cloudfront. net/websites/website1/websites/website1/about/”重定向到“example.cloudfront.net/about/”)

缺点是添加新分布时需要记得修改路由规则

<RoutingRules>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>websites/website1/websites/website1/</KeyPrefixEquals>
        </Condition>
        <Redirect>
            <HostName>example.cloudfront.net</HostName>
            <ReplaceKeyPrefixWith></ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
</RoutingRules>

【讨论】:

我尝试使用此示例,但没有像您的示例中那样附加斜杠。相反,我得到了我的 CNAME www.my-cname.com/about 与 www.my-cname.com/about/ 最终导致“重定向过多”。 我有一个类似的问题,部署了多个 Angular 站点,并使用 Lambda@Edge 解决了它。查看***.com/questions/49066634/…

以上是关于使用 S3、CloudFront 和源路径的静态网站托管的子文件夹重定向问题的主要内容,如果未能解决你的问题,请参考以下文章

CloudFront 使用路径前缀重定向所有请求

使用 S3 和 Cloudfront 的静态 Web 应用程序版本控制

在 CloudFront/S3 中托管 Angular 应用程序 *无需* S3 静态网站托管

使用 CloudFront 和目录重定向的 AWS S3 静态网站托管

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

将 Amazon S3 存储桶和 Cloudfront 与 SSL Wordpress 站点一起使用不会提供静态文件