重定向到index子文件夹的S3子文件夹

时间:2018-03-03 09:30:59

标签: amazon-web-services amazon-s3 amazon-cloudfront amazon-route53

我有一个域example.com。我有一个名为example.com的S3存储桶,其中包含一个index.html文件。现在,我想创建两个名为oldnew的子文件夹,每个子文件夹包含单个页面应用程序的单独版本。请求https://example.com/old(我想在浏览器的地址栏中输入请求时忽略index.html)将打开index.html子文件夹中的old文件并请求https://example.com/new会打开index.html。执行这些重定向的最佳方法是什么?我应该在Route 53中设置一些内容example.com/old - > example.com/old/index.html还是有更好的方法吗?

7 个答案:

答案 0 :(得分:12)

不需要lambda函数,这会增加项目的费用和复杂性。

以下答案引自https://stevepapa.com/

  

rdr[3].ToString("MM/dd/yyyy") 的工作方式应与https://stevepapa.com/my-great-new-post/

     

有一种巧妙的方法可以使这些流进入Cloudfront发行版,并且涉及将源原点从Cloudfront呈现给您的默认源更改。

     

选择原始来源时,Cloudfront将显示一个S3存储桶列表。   editing origin

     

您无需从下拉列表中显示的存储桶中设置源,而是需要从其S3设置页面中获取该资源的静态网络托管端点,然后手动将其弹出。 where the static hosting endpoint url is

     

使用Cloudfront分发源的静态源意味着对该分发的任何请求都将使用S3的根对象查找,并且您的404响应应在引用流过时消失。

重要: 完成此操作后,清除浏览器缓存和devalidate the items in your cloudfront distribution。否则,您所做的更改将不会立即生效。

答案 1 :(得分:4)

所以我昨晚也遇到了这个问题。

问题如下: 配置为网站存储桶时的S3是宽容的并且具有索引文档设置,设置为index.html并且在根处应用,即,example.com实际上被重定向到example.com/index.html,并且它也会在子文件夹级别应用,因此example.com/newexample.com/new/都应重定向到example.com/new/index.html,其中会有一个对象在桶中。 (如果没有,您将收到NoSuchKey错误。)

然而,你那么"升级"您自己可以使用CloudFront,可能是HTTPS,这个功能就消失了。相反,CloudFront会对S3进行显式API调用,因此不会触发索引文档让步。它适用于root用户,但不适用于子文件夹。

RoutingRules解决方案对我来说并不干净,因为通过指定KeyPrefixEquals而非关键字恰好等于(不存在),我认为您无意中匹配。

我改为实现了一个Lambda @ Edge规则,该规则重写了CloudFront向S3发出的请求,以便在其中包含正确的键值。

从Lambda文档和A / B测试示例开始: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-examples.html#lambda-examples-general-examples

将代码更改为:

'use strict';

exports.handler = (event, context, callback) => {
    /*
     * Expand S3 request to have index.html if it ends in /
     */
    const request = event.Records[0].cf.request;
    if ((request.uri !== "/") /* Not the root object, which redirects properly */
        && (request.uri.endsWith("/") /* Folder with slash */
            || (request.uri.lastIndexOf(".") < request.uri.lastIndexOf("/")) /* Most likely a folder, it has no extension (heuristic) */
            )) {
        if (request.uri.endsWith("/"))
            request.uri = request.uri.concat("index.html");
        else
            request.uri = request.uri.concat("/index.html");
    }
    callback(null, request);
};

并将其发布到您的CloudFront分配。

答案 2 :(得分:0)

  1. 配置您的Bucket以提供静态网站
  2. 创建CloudFront Distribution:将您的广告资源设为Origin,并将OriginPath设为空(默认值为/
  3. 创建链接到Route53
  4. CloudFront Distribution RecordSet

    您可以找到有用的演练here

    问题:如果您的客户输入example.com(没有old / new)会怎样?

    修改:2.是可选的。您还可以将Route53 RecordSet链接到您的静态网站,但 CloudFront可让您通过httpsAWS Certificate Manager的帮助)为您的wesbite提供服务。

答案 3 :(得分:0)

您可以尝试设置重定向规则,这是一个未经测试的规则。

<RoutingRules>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>old</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyWith>old/index.html</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>new</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyWith>new/index.html</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>

答案 4 :(得分:0)

使用HTML重定向文件可以更轻松地完成此操作

  1. 创建一个名为my-great-new-post的普通文件(不用担心不会与同一存储桶中的文件夹发生名称冲突)

  2. 在该文件中写一个元重定向代码(我在下面粘贴了代码)

  3. 将文件上传到根存储桶(my-great-new-post文件夹所在的位置)

  4. 修改新文件的元数据,并使Content-Type:text / html

在此放置文件的内容:

<!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="refresh" content="0; url=/my-great-new-post/index.html">
    </head>
    <body>
    </body>
    </html>

答案 5 :(得分:0)

如果您正在使用CDK通过S3源创建CloudFrontWebDistribution,那么您的第一个猜测可能就是这样做:

                OriginConfigs = new[] {
                    new SourceConfiguration {
                        S3OriginSource = new S3OriginConfig
                        {
                            S3BucketSource = bucket
                        }
                        Behaviors = new[] { new Behavior { IsDefaultBehavior = true } }
                    }
                }

但是,要将Cloudfront配置为使用website-bucket-url(确实具有将目录解析为index.html的行为),则需要使用:

                OriginConfigs = new[] {
                    new SourceConfiguration {
                        CustomOriginSource = new CustomOriginConfig
                        {
                            DomainName = bucket.BucketWebsiteDomainName,
                            OriginProtocolPolicy = OriginProtocolPolicy.HTTP_ONLY
                        },
                        Behaviors = new[] { new Behavior { IsDefaultBehavior = true } }
                    }
                }

您需要将协议指定为HTTP_ONLY,因为网站存储桶不支持HTTPS。 CustomOriginSource的默认值为HTTPS_ONLY。

答案 6 :(得分:0)

当您使用 S3 启用和配置静态托管时,您需要通过存储桶网站端点访问该站点。您可以在静态网站托管部分的存储桶属性中找到此 URL。

S3 Static website hosting settings

网站端点的 URL 将如下所示:

http://example-bucket.s3-website-eu-west-1.amazonaws.com/example-folder/

然而(令人困惑)存储在 S3 中的对象也可以通过不同的 URL 访问,这个 URL 不遵守子文件夹的索引规则。该网址如下所示:

https://example-bucket.s3-eu-west-1.amazonaws.com/example-folder/