.htaccess重定向破坏文件路径及URL规范化规则异常求助
我之前也踩过这个坑——在添加URL规范化规则后,原本运行好好的隐藏.html/.php后缀的重写规则突然失效,特别是访问带www的带路径页面时,直接被踢去无www的首页,折腾了好半天才理清问题根源。
大概率是规则执行顺序搞反了,或者规范化规则没保留请求路径导致的。下面给你一套可直接用的解决方案,一步步来:
第一步:先处理隐藏文件后缀的内部重写
内部重写是Apache在服务器内部偷偷匹配文件,不会改变浏览器地址栏的URL,这一步必须放在最前面,确保服务器能找到对应的.html/.php文件,再处理域名的重定向。
在你的.htaccess里先加上这段代码:
# 跳过真实存在的文件和目录,避免干扰 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # 隐藏.html后缀:如果请求的路径加上.html存在,就内部重写 RewriteCond %{REQUEST_FILENAME}\.html -f RewriteRule ^(.*)$ $1.html [L] # 隐藏.php后缀:同理处理php文件 RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule ^(.*)$ $1.php [L]
这里的[L]标记是告诉Apache:“这条规则匹配到就停,别往下走了”,避免后续规则干扰内部重写逻辑。
第二步:添加URL规范化规则(保留请求路径)
之前的问题很可能是你的规范化规则直接把所有带www的请求跳转到首页,而没保留原路径。下面的规则会完整保留用户访问的路径,比如www.yourdomain.com/about-us会跳转到yourdomain.com/about-us,而不是首页。
如果你要把www域名跳转到无www主域名:
# 匹配带www的域名(NC表示忽略大小写) RewriteCond %{HTTP_HOST} ^www\.yourdomain\.com$ [NC] # 保留原请求路径($1对应前面的^(.*)$),做301永久重定向 RewriteRule ^(.*)$ https://yourdomain.com/$1 [R=301,L]
如果你要把无www域名跳转到www域名:
把上面的规则反过来就行:
RewriteCond %{HTTP_HOST} ^yourdomain\.com$ [NC] RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R=301,L]
关键注意事项
- 规则顺序绝对不能乱:内部重写(隐藏后缀)必须放在外部重定向(URL规范化)之前,否则Apache会先把请求跳转到目标域名,但此时还没处理后缀隐藏,服务器找不到对应文件就会跳转到首页。
- 清空浏览器缓存再测试:301重定向是被浏览器永久缓存的,之前错误的重定向记录可能会影响测试结果,建议用隐私窗口测试。
- 确认mod_rewrite已启用:如果规则还是不生效,检查Apache是否开启了mod_rewrite模块(可以通过phpinfo()查看,或者联系主机服务商确认)。
按照这个顺序调整后,应该就能同时实现隐藏后缀和URL规范化的功能了,带www的带路径页面也会正确跳转到对应无www页面,而不是首页。
内容的提问来源于stack exchange,提问作者Matt Hammond
相关产品推荐
相关产品推荐

