.htaccess将非www及HTTP重定向至HTTPS://www.domainName异常排查
.htaccess 强制重定向部分失效排查与解决
我配置.htaccess强制重定向时碰到问题:输入http://domainName或直接敲domainName,能正常跳转到https://www.domainName/;但输入http://domainName/commercial这类带路径的地址,却只会重定向到https://domainName/commercial,没自动加上www前缀。试了三种规则,结果全一样:
尝试过的三种规则
方案1
RewriteCond %{HTTP_HOST} ^domainName$ [NC] RewriteRule ^(.*) https://www.domainName/$1 [R=301,L]
方案2
RewriteCond !{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteCond %{HTTP_HOST} !^www\. RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
方案3(交换方案2的规则顺序)
RewriteCond %{HTTP_HOST} !^www\. RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
预期与实际结果
- 预期:
https://www.domainName/commercial - 实际:
https://domainName/commercial
问题原因及解决办法
1. 先修正规则里的语法错误
方案2的第一个条件RewriteCond !{HTTPS} off写错了,多了个感叹号,正确判断HTTPS未启用的条件应该是RewriteCond %{HTTPS} off,语法错误直接导致这条规则失效,后续的www跳转逻辑也没按预期触发。
2. 用合并规则同时处理HTTPS和www跳转
最好把HTTPS启用和www前缀添加合并成一组规则,一次完成跳转,既避免两次跳转的性能损耗,也能确保路径被正确传递。推荐用下面两种写法:
写法一(清晰拆分场景)
RewriteEngine On # 处理非www且非HTTPS的请求 RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://www.domainName/$1 [R=301,L] # 处理非www但已HTTPS的请求 RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteRule ^(.*)$ https://www.domainName/$1 [R=301,L] # 处理www但非HTTPS的请求 RewriteCond %{HTTP_HOST} ^www\.domainName$ [NC] RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://www.domainName/$1 [R=301,L]
写法二(简洁合并)
RewriteEngine On # 只要不是www开头,或者HTTPS没启用,就跳转到目标地址 RewriteCond %{HTTP_HOST} !^www\.domainName$ [NC,OR] RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://www.domainName/$1 [R=301,L]
3. 务必清除浏览器缓存
因为之前用了R=301永久重定向,浏览器会缓存旧的跳转规则,哪怕你改了.htaccess,浏览器还是会走旧缓存。可以用这几种方式测试:
- 打开浏览器隐私/无痕窗口测试新规则
- 手动清除浏览器的缓存和Cookie
- 临时把
R=301改成R=302(临时重定向),确认生效后再改回R=301
特殊情况:服务器用了反向代理
如果你的服务器用了Cloudflare、Nginx反向代理这类服务,%{HTTPS}变量可能无法正确判断请求是否为HTTPS,需要改用X-Forwarded-Proto头判断:
RewriteEngine On RewriteCond %{HTTP:X-Forwarded-Proto} !https [OR] RewriteCond %{HTTP_HOST} !^www\.domainName$ [NC] RewriteRule ^(.*)$ https://www.domainName/$1 [R=301,L]
内容的提问来源于stack exchange,提问作者BlueManta
相关产品推荐
相关产品推荐

