通过htaccess将带末尾斜杠的URL重定向至无斜杠URL及问题排查
.htaccess规则解析与问题解决
一、原有规则逐行解析
先看你提供的原有规则:
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteRule ^nl/wp-login.php /wp-login.php [QSA,L] RewriteRule ^en/wp-login.php /wp-login.php [QSA,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] RewriteRule ^(.+)/$ /$1 [NE,R=301,L] </IfModule>
每条规则的作用:
<IfModule mod_rewrite.c>:仅在服务器启用mod_rewrite模块时执行内部规则,避免模块未开启时报错。RewriteEngine On:开启URL重写功能,所有重定向/转发规则依赖这条。RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]:将请求头的Authorization值传递给环境变量,供WordPress后台验证使用(比如API调用、第三方登录),属于必要规则,不能删除。RewriteBase /:设置重写基准路径为网站根目录,确保规则在子目录部署时也能正常工作。RewriteRule ^index\.php$ - [L]:如果请求的是首页index.php,直接跳过后续规则,避免重复处理。RewriteRule ^nl/wp-login.php /wp-login.php [QSA,L]:将nl子目录下的登录请求转发到根目录wp-login.php,保留原请求参数(QSA),处理后停止后续规则(L)。RewriteRule ^en/wp-login.php /wp-login.php [QSA,L]:和上一条类似,处理en子目录的登录页请求。RewriteCond %{REQUEST_FILENAME} !-f+RewriteCond %{REQUEST_FILENAME} !-d:判断请求的不是真实存在的文件或目录。RewriteRule . /index.php [L]:满足上面两个条件时,将所有请求转发到index.php,这是WordPress实现伪静态路由的核心规则。RewriteRule ^(.+)/$ /$1 [NE,R=301,L]:你需要的末尾斜杠重定向规则,但它被放在了核心路由规则之后。由于核心规则已经拦截了所有非真实文件/目录的请求,这条规则永远不会被触发,所以之前没有效果。
二、可删除的规则
如果你的网站没有nl/en多语言子目录的登录页需求,以下两条规则可以直接删除:
RewriteRule ^nl/wp-login.php /wp-login.php [QSA,L] RewriteRule ^en/wp-login.php /wp-login.php [QSA,L]
其余规则均为WordPress运行或你需要的重定向功能所必需,不建议删除。
三、重定向循环问题的解决
调整规则顺序后,末尾斜杠重定向生效,但/wp-admin出现循环,原因是:wp-admin是服务器上真实存在的目录,当你访问/wp-admin/时,重定向规则会把它转到/wp-admin;但WordPress后台会自动跳回带斜杠的/wp-admin/,形成无限循环。
解决方案
修改末尾斜杠重定向规则,添加条件排除真实存在的目录:
# 仅对非真实目录的请求,执行末尾斜杠重定向 RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.+)/$ /$1 [NE,R=301,L]
最终完整规则
整合后的.htaccess规则如下:
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] # 排除真实目录的末尾斜杠重定向 RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.+)/$ /$1 [NE,R=301,L] # 多语言登录页转发(不需要可删除) RewriteRule ^nl/wp-login.php /wp-login.php [QSA,L] RewriteRule ^en/wp-login.php /wp-login.php [QSA,L] # WordPress核心路由规则 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>
内容的提问来源于stack exchange,提问作者Kevin Kater
相关产品推荐
相关产品推荐

