Apache mod_rewrite中RewriteRule的NE标志(无转义)失效问题
解决Apache RewriteRule处理URL编码字符(如%2B)的重定向问题
这个问题我之前也碰到过,核心原因是**%{REQUEST_URI}会自动解码URL编码的特殊字符**——当请求里的%2B(也就是+的URL编码)经过Apache处理时,会被转换成明文的+,再通过%1引用到重定向目标里,就导致原本的编码丢失,出现不符合预期的重定向结果。
修正后的Rewrite规则方案
我们可以改用%{THE_REQUEST}变量来匹配,它保存的是浏览器发送的原始请求行,不会被Apache解码,能完整保留URL里的编码字符。修改后的规则如下:
RewriteCond %{HTTP_HOST} ^(www\.)?sample\.com$ RewriteCond %{THE_REQUEST} ^[A-Z]+\ /do/([^\s]+) RewriteRule ^do/.* http://sub.sample.com/some/test/do/%1 [R=302,L]
规则说明
%{THE_REQUEST}的格式类似GET /do/PjX7%2Bj69 HTTP/1.1,正则^[A-Z]+\ /do/([^\s]+)会精准捕获/do/后面直到空格的所有内容,这个%1就是原始的编码字符串(包含%2B)。RewriteRule ^do/.*只是用来触发规则的匹配条件,实际重定向的路径内容来自%{THE_REQUEST}的捕获结果。- 标志
R=302表示临时重定向,测试阶段建议用这个避免浏览器缓存问题;如果是永久重定向需求,改成R=301即可;L表示这是最后一条规则,避免后续规则干扰。
这样修改后,当请求http://www.sample.com/do/PjX7%2Bj69时,重定向后的URL会准确保留%2B编码,变成http://sub.sample.com/some/test/do/PjX7%2Bj69,完全符合你的预期。
内容的提问来源于stack exchange,提问作者Vahid
相关产品推荐
相关产品推荐

