.htaccess伪静态配置:双URL归一化跳转及参数保留问题
现有规则的问题
- 只实现了伪静态路径到动态脚本的内部转发,缺少动态路径到伪静态路径的外跳规则,才会出现同一内容两个URL可访问的重复问题,影响SEO权重归集和用户体验
- 原有规则没有做真实资源判断,只要是3-10位字母数字组成的根路径,不管是不是真实存在的静态文件、目录,都会被强制转发给
index.php,容易造成原有静态资源访问异常 - 没有匹配请求类型和参数格式,跳转规则如果不做参数范围限制,容易出现无效跳转、恶意路径匹配的问题
补充实现方案
所有规则写在站点根目录的.htaccess文件(或Apache虚拟主机配置段)里,注意跳转规则必须放在原有内部重写规则的前面,否则会触发重写死循环,完整规则如下:
# 重写引擎已开启的话无需重复添加这行 RewriteEngine On # --------------- 新增的动态地址跳转规则 --------------- # 匹配请求目标为根目录下的index.php RewriteCond %{REQUEST_URI} ^/index\.php$ # 匹配查询参数中act值为3-10位字母数字,和原有规则的匹配范围完全对齐 RewriteCond %{QUERY_STRING} ^act=([A-Za-z0-9]{3,10})$ # 301永久跳转到伪静态地址,QSD标记用于丢弃原URL的查询参数,避免地址栏残留?act=xxx # 注意:如果使用Apache 2.2及更早版本,去掉QSD标记,把跳转目标写成/%1? 即可,末尾问号同样可以丢弃原参数 RewriteRule ^index\.php$ /%1 [R=301,L,QSD] # --------------- 优化后的原有内部重写规则 --------------- # 新增判断:当前请求路径不是真实存在的文件 RewriteCond %{REQUEST_FILENAME} !-f # 新增判断:当前请求路径不是真实存在的目录 RewriteCond %{REQUEST_FILENAME} !-d # 原有转发逻辑保持不变,后端可以正常获取act参数,无需修改业务代码 RewriteRule ^([A-Za-z0-9]{3,10})$ index.php?act=$1 [L]
配置注意事项
- 测试规则阶段建议先把
R=301改成R=302临时重定向,确认跳转逻辑完全正常后再切回301永久重定向,避免浏览器缓存错误跳转规则影响正常访问 - 规则里的
%1是引用前面RewriteCond中正则捕获的act参数值,和原有重写规则的参数匹配范围完全一致,不会出现参数错位、不匹配的问题 - 加了真实文件/目录判断后,站点根目录下已有的静态文件、图片、后台目录等资源不会被误转发,原有访问逻辑不受影响
执行流程说明
- 用户访问动态地址
http://domen.com/index.php?act=rules时,优先匹配跳转规则,服务器返回301状态码告知浏览器跳转到http://domen.com/rules,此时地址栏自动更新为简洁的伪静态地址 - 浏览器自动请求伪静态地址
/rules,此时不会触发跳转规则,匹配内部重写逻辑,将请求隐式转发给index.php,后端正常读取act=rules参数渲染页面,业务逻辑完全不需要改动 - 最终两个地址只会对外暴露伪静态这一个访问入口,彻底解决URL重复问题
内容的提问来源于stack exchange,提问作者VR.Arta
相关产品推荐
相关产品推荐

