带变量的.htaccess RewriteRule规则失效,跳转至错误页面
.htaccess URL重写规则失效的解决方法
问题根源分析
你当前的规则存在几个核心问题:
- 规则方向搞反:你写的
RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]是把/latest/xxx内部重写成/latest?auth=xxx,但你需要的是反过来——把带auth参数的旧URL跳转到路径形式的新URL,这需要外部跳转规则(带R标志)。 - 规则位置错误:这条规则放在了CI路由规则和PHP后缀移除规则之后,请求会先被前面的规则拦截处理,根本轮不到它生效。
- 正则匹配不全:你的
auth值包含连字符(比如US-mobile-county),但正则[A-Za-z0-9]+没包含连字符,导致匹配失败。 - MultiViews干扰:
Options +MultiViews会让Apache自动匹配文件(比如访问/latest时自动找latest.php),打乱规则逻辑。
修改后的完整.htaccess代码
# BEGIN - Allow Sucuri Services <IfModule mod_rewrite.c> RewriteRule ^sucuri-(.*)\.php$ - [L] </IfModule> # END - Allow Sucuri Services <Files 403.shtml> order allow,deny allow from all </Files> ErrorDocument 404 /404.php # 关闭MultiViews避免自动匹配文件 Options +FollowSymLinks -MultiViews RewriteEngine on # 强制HTTPS RewriteCond %{HTTPS} !=on RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L] # 强制WWW域名 RewriteCond %{HTTP_HOST} !^www.xxxxx.com$ [NC] RewriteRule ^(.*)$ https://www.xxxxx.com/$1 [L,R=301] # 1. 外部跳转:把带auth参数的旧URL跳转到新路径 RewriteCond %{QUERY_STRING} ^auth=([A-Za-z0-9-]+)$ RewriteRule ^latest$ /latest/%1? [R=301,L,NC] # 2. 内部重写:把新路径转成带auth参数的格式供后端处理 RewriteRule ^latest/([A-Za-z0-9-]+)$ latest?auth=$1 [NC,L] # CI框架路由规则 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ ci_index.php?/$1 [L] ## 移除PHP后缀(排除latest路径避免干扰) RewriteCond %{REQUEST_URI} !^/index.php$ RewriteCond %{REQUEST_URI} !^/latest/ RewriteRule ^([^\.]+)$ $1.php [NC,L]
关键调整说明
- 关闭MultiViews:添加
-MultiViews避免Apache自动解析文件,确保URL规则完全由RewriteRule控制。 - 新增外部跳转规则:用
RewriteCond匹配auth参数,再通过RewriteRule跳转到路径形式,末尾的?用于清除原查询字符串,R=301表示永久跳转(利于SEO)。 - 调整内部重写规则位置:把它放在CI路由规则之前,确保
/latest/xxx先被重写成/latest?auth=xxx,再交给CI框架处理。 - 修正正则匹配:在正则里加入
-,确保能匹配带连字符的auth值。 - 修改PHP后缀移除规则:添加
RewriteCond %{REQUEST_URI} !^/latest/,避免把/latest/xxx错误重写成/latest/xxx.php。
内容的提问来源于stack exchange,提问作者GurusGuru
相关产品推荐
相关产品推荐

