301重定向异常:旧页面URL出现在查询字符串中
解决Apache Rewrite规则与301重定向冲突问题
现有可正常运行的Apache URL重写规则如下:
RewriteEngine On RewriteBase /a/b/ RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)/?$ index.php?slug=$1 [QSA,L]
该规则可正确处理https://www.example.com/a/b/testing这类URL的访问请求。
遇到的问题
添加以下Redirect指令后:
Redirect 301 /oldurl /newurl
访问原URL时,最终跳转后的地址为https://www.example.com/a/b/newurl?slug=oldurl,而期望的正确地址是https://www.example.com/a/b/newurl。
问题原因
Redirect属于mod_alias模块指令,RewriteRule属于mod_rewrite模块指令,二者在Apache中的执行顺序不同:mod_alias的重定向先触发,跳转后的新URL会再次经过mod_rewrite的规则处理,导致原路径被当作slug参数追加到新URL后。
解决方案
不要混用mod_alias和mod_rewrite指令,改用mod_rewrite的RewriteRule实现301重定向,并将重定向规则放在现有Rewrite规则的最前面,同时添加L标记终止后续规则执行。
修改后的完整规则如下:
RewriteEngine On RewriteBase /a/b/ # 301重定向规则,优先执行 RewriteRule ^oldurl$ newurl [R=301,L] # 原有URL重写规则 RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)/?$ index.php?slug=$1 [QSA,L]
说明
L标记确保重定向规则执行后,不再触发后续的Rewrite规则,避免slug参数被追加。- 由于设置了
RewriteBase /a/b/,重定向目标使用相对路径newurl即可,也可以写成绝对路径/a/b/newurl,效果一致。 - 301重定向会被浏览器缓存,测试时建议清空浏览器缓存或使用隐私模式访问,避免旧缓存干扰结果。
内容的提问来源于stack exchange,提问作者Naren Verma
相关产品推荐
相关产品推荐

