如何将子域名及附加域名301重定向至SSL CloudFront分发?
嘿,我懂你的痛点——当CloudFront作为CDN挡在源站前面时,源站的.htaccess规则经常因为请求路由优先级的问题不生效,毕竟请求先到CloudFront节点,而非直接打到你的Elastic Beanstalk服务。下面给你针对两种场景的可靠解决方案,都是基于CloudFront本身的配置,比改源站更高效且稳定:
一、将www.example.com 301重定向到 https://example.com
这里有两种常用方案,你可以根据自己的需求选择:
方案1:用CloudFront行为配置直接重定向
这种方式不需要写代码,适合简单场景:
- 先确保
www.example.com已经添加到CloudFront分发的**备用域名(CNAMEs)**列表中,并且对应的DNS解析(比如在Route 53里)已经将www.example.com别名指向CloudFront的分发域名。 - 进入CloudFront控制台,找到你的分发,切换到**行为(Behaviors)**标签页,点击「创建行为」:
- 路径模式填
*(匹配所有请求路径) - 源域名选择你的Elastic Beanstalk源站
- 下拉到重定向设置,选择「自定义重定向」
- 按以下参数配置:
- 协议:选择
HTTPS - 主机:填写
example.com - 路径:保留原有路径(Keep path)
- 查询字符串:保留原有查询字符串(Keep query string)
- HTTP状态码:选
301 - Permanent Redirect
- 协议:选择
- 保存行为后,记得调整优先级——这个针对
www的行为要比默认行为优先级更高(数字越小优先级越高)。
- 路径模式填
方案2:用CloudFront函数实现灵活重定向
如果之后还要加更多重定向规则,用CloudFront函数更方便:
- 进入CloudFront控制台的「函数」页面,创建一个新的查看器请求函数,粘贴以下代码:
function handler(event) { const request = event.request; const host = request.headers.host.value; // 匹配www子域名 if (host === 'www.example.com') { return { statusCode: 301, statusDescription: 'Moved Permanently', headers: { location: { value: `https://example.com${request.uri}` } } }; } // 其他请求正常转发到源站 return request; }
- 发布这个函数,然后回到你的CloudFront分发行为设置,编辑对应行为(或者新建行为),在「函数关联」部分选择刚才创建的函数,触发类型选「查看器请求」。
二、将example2.com 301重定向到 https://example.com
这个场景和子域名类似,但需要额外注意证书和DNS配置:
- 先在AWS Certificate Manager(ACM)中申请包含
example2.com的SSL证书(必须部署在us-east-1区域,因为CloudFront只认这个区域的证书),然后将该证书关联到你的CloudFront分发。 - 把
example2.com添加到CloudFront分发的备用域名(CNAMEs),并在DNS服务商(比如Route 53)将example2.com的A/AAAA记录别名指向CloudFront分发域名。
之后同样可以用两种方案实现重定向:
方案1:CloudFront行为配置
创建新的行为,路径模式*,源域名可以任选(因为我们会直接重定向,不需要回源),然后在重定向设置里配置:
- 协议:
HTTPS - 主机:
example.com - 路径:保留原有路径
- 查询字符串:保留原有
- 状态码:301
方案2:扩展CloudFront函数
把之前的函数代码修改一下,同时支持www.example.com和example2.com:
function handler(event) { const request = event.request; const host = request.headers.host.value; const targetDomain = 'https://example.com'; // 匹配需要重定向的域名 if (['www.example.com', 'example2.com'].includes(host)) { // 保留原有路径和查询字符串 const fullPath = `${request.uri}${request.querystring ? '?' + request.querystring : ''}`; return { statusCode: 301, statusDescription: 'Moved Permanently', headers: { location: { value: `${targetDomain}${fullPath}` } } }; } return request; }
发布后关联到CloudFront行为即可。
为什么你的.htaccess规则没生效?
主要原因是CloudFront作为前端CDN,请求会先被边缘节点处理,如果节点有缓存或者配置了直接响应(比如重定向),请求根本不会到达你的Elastic Beanstalk源站,自然不会触发.htaccess的规则。而且在CDN层做重定向,能减少回源请求,提升访问性能,比源站处理更优。
最后提醒:CloudFront配置修改后,需要等待5-15分钟让边缘节点同步配置,之后再测试重定向是否生效。
内容的提问来源于stack exchange,提问作者Matthew James Taylor
相关产品推荐
相关产品推荐

