我使用 CloudFront 在 S3 上托管静态网站。
现在,
www.example.com
和example.com
都返回相同的结果,但我只希望example.com
工作,并且www.example.com
重定向到example.com
。
我知道我可以创建另一个存储桶,它将重定向到主存储桶 (
example.com
),但随后我将为每个网站创建两个存储桶和两个 CloudFront 分配,这会造成混乱。
还有其他方法可以实现这一点吗?
最近 AWS 推出了 Cloudfront Functions。正如您所猜测的,它允许您使用自定义函数代码在云端操作 http 请求/响应。
在他们的介绍性博客中,他们介绍了这个特定的重定向用例。根据他们的博客介绍 CloudFront Functions – 在任意规模的边缘以低延迟运行代码:-
URL 重写和重定向:生成响应以将请求重定向到不同的 URL。例如,将未经身份验证的用户从受限页面重定向到登录表单。 URL 重写也可用于 A/B 测试。
我已经尝试过这种方法。我做了什么:-
redirect_www_to_naked
function
与此发行版相关联。www
中的
Route 53
这就是我的函数的样子:-
编辑: 我写了一篇关于它的博客,详细解释了您是否想了解更多信息 - 使用 CloudFront Function 将 WWW 重定向到裸域
花了很多时间,搜索并尝试不同的解决方案,无论是在 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 开头,则将其重定向到裸地址。否则,它将返回未更改的请求。
当然,不要忘记保存您的函数,然后发布它。执行此操作后,您必须将其关联到您的发行版。
除了@Wilhelm Sorban
您可以这样设置位置以不包含域名:
'location': { value: 'https://'+request.headers["host"].value.replace('www.', '')+event.request.uri }
但是我在Cloudfront函数文档中没有找到协议(http或https)的任何标头值:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/functions-event-struct.html#functions-事件结构请求
您提到 example.com 时似乎正在使用 DNS 服务
不过,我不知道你在做什么 DNS 服务。
由于53号路线比较常用,所以以53号路线为基础进行描述。
域是在 example.com 的基础上描述的。
您可以通过编程方式编写从 example.com 到 www.example.com 的重定向。
但是,通常在 AWS 级别解决此问题。
需要两个存储桶才能在 AWS 级别进行解析。
然后,如果您请求 www.example.com,您将被重定向到 example.com。
如有任何疑问,请随时询问!
谢谢你。
更新1
如果您激活 example.com 和 www.example.com 的 CloudFront CNAME,
只需一个存储桶即可获取 example.com 和 www.example.com 请求。
但是不建议这样做,因为URL的一致性不好。
这里提供的精彩答案的一点补充:
我在原始的cloudfront发行版上使用了提供的代码。添加了 www 到它,这样它就可以同时服务 www 和 bare,并且该函数确实重定向 - 基本上到它自己。
还稍微更改了函数以使用查询字符串进行重定向:
'location': { value: 'https://'+request.headers["host"].value.replace('www.', '')+event.request.uri.replace("https://","").replace("http://","").replace(request.headers["host"].value,"") }
这对我有用
1- 创建了一个新的 cloud Front 发行版,并使其引用与原始发行版相同的 s3 存储桶。
2- 在路由 53 中创建一条新记录,为其添加前缀 www.example.com 并使其引用新创建的云前端分布。
然后,如果您输入 example.com 或 www.example.com ,它们将重定向到同一个存储桶,并且两者工作正常
希望这有帮助。