将S3 / CloudFront中的www重定向到非www,而无需单独使用存储桶

11
我正在使用S3和CloudFront托管静态网站。现在,www.example.comexample.com 都会返回同样的结果,但我只想让 example.com 生效,而将 www.example.com 重定向到 example.com。 我知道我可以创建另一个桶来重定向到主桶(example.com),但那样我就需要为每个网站创建两个桶和两个CloudFront分布,这会很混乱。有没有其他方法可以实现这一点?

我投票关闭了这个问题,因为它不是一个编程问题,并且在Stack Overflow上是离题的。关于你的网站的非编程问题应该在[webmasters.se]上提问。将来请在那里提问,而不是在这里。 - Stephen Ostermiller
6个回答

8
最近AWS推出了Cloudfront函数。正如你所猜测的那样,它允许您使用自定义函数代码在云前端中操作http请求/响应。
在他们的介绍性博客中,他们涵盖了这个特定的重定向用例。根据他们的博客Introducing CloudFront Functions – Run Your Code at the Edge with Low Latency at Any Scale:-
URL重写和重定向:生成响应以将请求重定向到不同的URL。例如,将未经身份验证的用户从受限页面重定向到登录表单。URL重写也可用于A/B测试。
我已经尝试过这种方法。我做了什么:
1.设置一个新的cloudfront分发。
2.将此分发映射到现有的网站存储桶(实际上并不重要)
3.将一个名为“redirect_www_to_naked”的新函数与此分发相关联。
4.将此分发映射到Route 53中的“www”子域。
这就是我的函数的样子:

enter image description here

这是我的关联设置 在此输入图片描述 编辑: 如果您想了解更多信息,我写了一篇博客详细说明 - 使用CloudFront函数将WWW重定向到裸域

每个网站请求都会触发该Lambda函数。不幸的是,这是大量的Lambda调用。是否可能在“源响应”中完成,而不是在“查看器请求”中完成? - grayaii
1
我无法访问您的文章,似乎已经失效了。 - Tobias Feil
1
显然,服务器崩溃了,因为由于国家法规,AWS无法收取我的信用卡费用。一旦我有时间,我会让它重新上线。@TobiasFeil - Paramvir Singh Karwal
1
只有当用户访问“www”域名时,它才会触发,随后的访问将不会触发该分发-因此没有Lambda调用。除非您的网站获得数百万次点击-Lambda成本不会很高...在这种情况下,S3存储桶网站可能不是合适的选择.. ;) 这是一个好问题... - Dan G

6
经过多个小时的搜索和尝试不同的解决方案,无论是在Cloudfront或Route53中,@Paramvir建议的解决方案最终帮助我找到了答案。
最终我使用了一个类似于以下代码的Cloudfront函数:
function handler(event) {
    var request = event.request;
    console.log(request.headers["host"]);
    if (request.headers["host"] && request.headers["host"].value.startsWith("www")) {
        var response = {
            statusCode: 301,
            statusDescription: 'Moved Permanently',
            headers: {
                'location': { value: 'https://naked_address.com'+event.request.uri }
            }
        };
        return response;
    }
    return request;
}

它的基本功能是检查请求地址,如果以www开头,则将其重定向到裸域。否则返回未更改的请求。

当然,不要忘记保存您的函数,然后进行发布。完成此操作后,必须将其与您的分发相关联。


你能帮我解决一个问题吗?在重定向时,如何保留查询参数?你的函数可以正确地进行重定向,但是它忽略了查询参数。 - Prateek
@Prateek 这是一个 CloudFront 参数 - 在行为设置中,您有一个下拉菜单可以选择要转发的查询字符串 - 无、全部或指定。 - Wilhelm Sorban
@Wihelm Soarban 我已经使用"All"来转发查询参数。所有的查询参数都能够正确地重定向,但是当CloudFront进行重定向时,它并没有发送查询参数。重定向URL本身正在删除查询参数,更不用说将其传递给源了。 - Prateek

1

这是通用的,因此同一个 Cloudfront 函数可以用于多个 Cloudfront 分发。 - undefined

0

您似乎正在使用DNS服务,因为您提到了example.com。
但是,我不知道您使用的是哪种DNS服务。
由于Route 53是常用的DNS服务,因此本文以Route 53为基础进行描述。
域名是以example.com为基础进行描述的。

您可以通过编程方式将example.com重定向到www.example.com。
然而,在AWS级别解决这个问题是很常见的。

在AWS级别解决这个问题需要两个存储桶。

  1. example.com(内容存储桶)

  2. www.example.com(重定向到example.com的存储桶)
    S3 -> 属性 -> 静态网站托管 -> 重定向请求
    目标存储桶或域名:example.com
    协议:http
    (存储桶不需要任何文件。)

  3. 将example.com映射到Route 53上的A记录。

  4. 将www.example.com映射到Route 53的A记录。

然后,如果您请求www.example.com,您将被重定向到example.com。

如果您有任何问题,请随时问我!
谢谢。

更新 1
如果你为 example.com 和 www.example.com 激活了 CloudFront CNAME,
你可以只使用一个存储桶来处理 example.com 和 www.example.com 的请求。
然而,不建议这样做,因为 URL 的一致性不好。


我了解你提到的方法,但正如我在问题中提到的:“我知道我可以创建另一个桶,将其重定向到主桶(example.com),但那样我就会有两个桶和每个网站两个CloudFront分配,这会让一切变得混乱。”我正在寻找一种不需要创建2个bucket的方法。 - Theodore
@Theodore 拥有两个存储桶并不意味着您正在部署两个 CloudFront。 仅为 example.com 存储桶创建一个部署。 www.example.com 存储桶是用于重定向到 example.com 域的存储桶。 - HEEWON
这些桶必须是公共的吗? - Glen Thompson
主要的存储桶(包含文件)必须是公共的... 权限> 存储桶策略 { "Version": "2008-10-17", "Statement": [ { "Sid": "PublicReadForGetBucketObjects", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::example.com/*" } ] } - fencepencil
3
这并没有回答问题,更糟的是完全忽略了避免使用两个存储桶的请求。更不用说将www映射到裸域并不会真正导致重定向,它只是从“www”相同的内容提供服务,我怀疑这不是请求的内容。除非“将www.example.com映射到Route 53的A记录”意味着映射到存储桶,否则你的意思不清楚。无论如何,根据我的理解,这并不是一个答案,因为它没有使用CloudFront的当前解决方案。 - Seivan
当我尝试导航到www网站时,它会显示“ERR_TOO_MANY_REDIRECTS”错误。 - Maurice

0
在这里提供的精彩答案上做一个小补充:
我在原始的CloudFront分发上使用了提供的代码。将"www"添加进去,这样它就可以同时为"www"和裸域名提供服务,而且这个函数会将重定向指向自身。
我还稍微修改了这个函数,以便可以带上查询字符串进行重定向。
'location': { value: 'https://'+request.headers["host"].value.replace('www.', '')+event.request.uri.replace("https://","").replace("http://","").replace(request.headers["host"].value,"") }

-2

这是对我有效的方法:

1- 创建一个新的云前端分发,并使其引用与原始分发相同的S3存储桶。

2- 在Route 53中创建一个新记录,给它前缀www.example.com,并使其引用新创建的云前端分发。

然后,如果您键入example.com或www.example.com,它们将重定向到同一个存储桶,两者都可以正常工作。

希望这有所帮助。


3
不幸的是,这对于SEO来说并不好,因为在搜索引擎的眼中,您现在有两个重复的网站。 - tyirvine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接