
在使用apache的mod_rewrite模块进行url重写时,开发者可能会遇到一个常见问题:rewriterule捕获的url参数意外地包含了尾部斜杠(/)。这通常发生在url路径的最后一个片段后带有可选斜杠,而重写规则未能正确区分时。
考虑以下.htaccess配置,旨在将形如/book/chapter/或/book/的URL重写为index.php并传递book和chapter参数:
RewriteEngine On RewriteRule ^(.+)/(.+)/?$ index.php?book=$1&chapter=$2 [NC,L,QSA] RewriteRule ^(.+)/?$ index.php?book=$1 [NC,L,QSA]
当访问以下URL时:
在index.php中打印$_REQUEST数组,可能会得到如下结果:
// 对于 mydomain.com/coding/mysql/ Array ( [book] => coding [chapter] => mysql/ ) // 对于 mydomain.com/coding/?contactId=333 Array ( [book] => coding/ [contactId] => 333 )
可以看到,chapter或book参数的值中意外地包含了尾部斜杠,这与预期(例如mysql而非mysql/)不符。
此问题的根源在于正则表达式的默认“贪婪”匹配行为。在上述规则中,(.+)是一个贪婪量词,它会尽可能多地匹配字符。当URL路径如coding/时,对于规则^(.+)/?$,(.+)会贪婪地匹配到coding/,而后面的/?则匹配空字符串。因此,捕获组$1的值就成了coding/。同理,对于^(.+)/(.+)/?$,如果路径是coding/mysql/,第二个(.+)可能会匹配mysql/,而/?匹配空,导致$2捕获到mysql/。
最直接且推荐的解决方案是,在匹配URL路径片段时,明确指定不包含斜杠。这可以通过使用字符集[^/]+来实现,它表示匹配一个或多个非斜杠字符。
修改后的.htaccess规则如下:
RewriteEngine On # 规则1: 匹配 /book/chapter/ 或 /book/chapter (无尾部斜杠) # $1 捕获 book, $2 捕获 chapter RewriteRule ^([^/]+)/([^/]+)/?$ index.php?book=$1&chapter=$2 [L,QSA] # 规则2: 匹配 /book/ 或 /book (无尾部斜杠) # $1 捕获 book RewriteRule ^([^/]+)/?$ index.php?book=$1 [L,QSA]
解析:
使用此配置后,对于mydomain.com/coding/mysql/,$_REQUEST将正确显示为:
Array ( [book] => coding [chapter] => mysql )
对于mydomain.com/coding/?contactId=333,$_REQUEST将显示为:
Array ( [book] => coding [contactId] => 333 )
上述[^/]+的解决方案虽然解决了参数中包含斜杠的问题,但过于通用的规则(如^([^/]+)/?$)可能会意外地匹配到服务器上的实际文件,例如mydomain.com/library.php。这会导致library.php被重写,而不是直接访问该文件。
为了避免这种情况,并进一步提高规则的精确性,我们可以在字符集中排除点号(.),从而避免匹配带有文件扩展名的路径。
RewriteEngine On # 规则1: 匹配 /book/chapter/ 或 /book/chapter,且book和chapter不含点号 RewriteRule ^([^/.]+)/([^/.]+)/?$ index.php?book=$1&chapter=$2 [L,QSA] # 规则2: 匹配 /book/ 或 /book,且book不含点号 RewriteRule ^([^/.]+)/?$ index.php?book=$1 [L,QSA]
解析:
核心原则: 编写RewriteRule时,应尽可能具体地匹配目标URL模式,避免使用过于宽泛的正则表达式,以防止意外匹配和不必要的重写。
虽然上述规则允许URL带或不带尾部斜杠都能正确解析参数,但在实际应用中,为了SEO(搜索引擎优化)和用户体验,强烈建议对URL尾部斜杠采取一致的策略:要么所有URL都带尾部斜杠,要么所有URL都不带尾部斜杠。
允许mydomain.com/path/和mydomain.com/path同时访问相同内容,会被搜索引擎视为“重复内容”,这可能对网站的排名产生负面影响。
推荐做法:
示例:强制所有目录型URL以斜杠结尾
# 确保所有目录型URL以斜杠结尾 (301重定向) # 排除
以上就是Apache RewriteRule参数中尾部斜杠问题的解析与优化的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号