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

问题描述 投票:0回答:6

我使用 CloudFront 在 S3 上托管静态网站。

现在,

www.example.com
example.com
都返回相同的结果,但我只希望
example.com
工作,并且
www.example.com
重定向到
example.com

我知道我可以创建另一个存储桶,它将重定向到主存储桶 (

example.com
),但随后我将为每个网站创建两个存储桶和两个 CloudFront 分配,这会造成混乱。

还有其他方法可以实现这一点吗?

amazon-web-services redirect amazon-s3 amazon-cloudfront no-www
6个回答
8
投票

最近 AWS 推出了 Cloudfront Functions。正如您所猜测的,它允许您使用自定义函数代码在云端操作 http 请求/响应。

在他们的介绍性博客中,他们介绍了这个特定的重定向用例。根据他们的博客介绍 CloudFront Functions – 在任意规模的边缘以低延迟运行代码:-

URL 重写和重定向:生成响应以将请求重定向到不同的 URL。例如,将未经身份验证的用户从受限页面重定向到登录表单。 URL 重写也可用于 A/B 测试。

我已经尝试过这种方法。我做了什么:-

  1. 设置新的 Cloudfront 发行版。
  2. 将此发行版映射到现有网站存储桶(并不重要)
  3. 将新的
    redirect_www_to_naked
    function
    与此发行版相关联。
  4. 将此分布映射到
    www
     中的 
    Route 53
  5. 子域

这就是我的函数的样子:-

这是我的关联设置

编辑: 我写了一篇关于它的博客,详细解释了您是否想了解更多信息 - 使用 CloudFront Function 将 WWW 重定向到裸域


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 开头,则将其重定向到裸地址。否则,它将返回未更改的请求。

当然,不要忘记保存您的函数,然后发布它。执行此操作后,您必须将其关联到您的发行版。


1
投票

除了@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-事件结构请求


0
投票

您提到 example.com 时似乎正在使用 DNS 服务
不过,我不知道你在做什么 DNS 服务。
由于53号路线比较常用,所以以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的一致性不好。


0
投票

这里提供的精彩答案的一点补充:

我在原始的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,"") }

-2
投票

这对我有用

1- 创建了一个新的 cloud Front 发行版,并使其引用与原始发行版相同的 s3 存储桶。

2- 在路由 53 中创建一条新记录,为其添加前缀 www.example.com 并使其引用新创建的云前端分布。

然后,如果您输入 example.com 或 www.example.com ,它们将重定向到同一个存储桶,并且两者工作正常

希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.