我们有这样的htaccess规则:
RewriteRule ^(.*)/(.*)/(.*) ../app$1/scripts/api/index.php?fn=$2&$3 [L]
这在大多数情况下都可以正常工作,但是,Apache在到达该规则之前会对URL进行解码,因此htaccess将类似beta/list/&cat=red%20%26%20blue
的URL视为beta/list/&cat=red & blue
,因此我们得到了{{1} }和cat='red'
进入blue=null
而不是index.php
。
我已经读到,解决此问题的方法是在htaccess规则中使用服务器变量,例如cat='red & blue'
%{REQUEST_URI}
,因为这些变量在使用前不会被解码,但是很难实现。 RewriteRule中的问号使一切变得疯狂,我不知道如何逃避它。
那里的任何专家都可以帮助我修正下面的规则,使其表现出与上面相同的方式吗?
%{THE_REQUEST}
答案 0 :(得分:1)
实际上,解决方案是使用名为THE_REQUEST
的特殊服务器变量。
THE_REQUEST
浏览器发送到服务器的完整HTTP请求行(例如, “ GET /index.html HTTP / 1.1”)。这不包括任何其他 浏览器发送的标头。 此值尚未释放 (已解码),与下面的大多数其他变量不同。
这是您的规则的外观
# don't touch urls ending by index.php
RewriteRule index\.php$ - [L]
# user request matching /xxx/xxx/xxx (with optional query string)
RewriteCond %{THE_REQUEST} \s/([^/\?]+)/([^/\?]+)/([^\?]+)(?:\s|\?) [NC]
RewriteRule ^ ../app%1/scripts/api/index.php?fn=%2&%3 [L,QSA]
请注意,您不应该使用相对路径进行内部重写,否则可能导致混乱。而是定义一个RewriteBase
,使用绝对路径或从域根开始以/
开始。
由于您可以在网址中编码正斜杠,因此需要将AllowEncodedSlashes
设置为NoDecode
(或On
,但这是不安全的)。另请注意,由于存在错误,即使据说 server config 上下文还可以,您也必须将此指令放入虚拟主机上下文中(否则,简单地忽略)。默认情况下,AllowEncodedSlashes
设置为Off
。因此,Apache会自动自行处理编码的斜杠并拒绝它们,而不会将请求传递给mod_rewrite
。请参阅官方文档here。