简体   繁体   English

重写规则以防止apache在到达htaccess之前解码url?

[英]Rewrite rule to prevent apache decoding url before reaching htaccess?

We have a htaccess rule like this: 我们有这样的htaccess规则:

RewriteRule ^(.*)/(.*)/(.*) ../app$1/scripts/api/index.php?fn=$2&$3 [L]

This works fine in most cases, however, Apache decodes the url before it arrives at this rule, so a url like beta/list/&cat=red%20%26%20blue , is seen by htaccess as beta/list/&cat=red & blue so we get cat='red' and blue=null coming into index.php instead of cat='red & blue' . 这在大多数情况下都可以正常工作,但是,Apache在到达此规则之前会对其进行解码,因此htaccess beta/list/&cat=red%20%26%20blue类似beta/list/&cat=red%20%26%20blue视为beta/list/&cat=red & blue所以我们将cat='red'blue=null放入index.php而不是cat='red & blue'

I've read that the workaround for this issue is to use server variables like %{REQUEST_URI} %{THE_REQUEST} in the htaccess rule as these are not decoded before use, but it's difficult to implement. 我已经读到,解决此问题的方法是在htaccess规则中使用服务器变量,例如%{REQUEST_URI} %{THE_REQUEST} ,因为这些变量在使用前不会被解码,但是很难实现。 The question mark in the RewriteRule makes everything go crazy and I can't figure out how to escape it. RewriteRule中的问号使一切变得疯狂,我不知道如何逃避它。

Can any experts out there help me fix the rule below to behave like the one above? 那里的任何专家都可以帮我解决以下规则,使其表现出与上面相同的行为吗?

RewriteCond %{REQUEST_URI} ^(.*)/(.*)/(.*)
RewriteRule . ../app%1/scripts/api/index.php?fn=%2&%3 [L]

Indeed, the solution is to use the special server-variable called THE_REQUEST . 实际上,解决方案是使用称为THE_REQUEST的特殊服务器变量。

From mod_rewrite documentation : mod_rewrite文档中

THE_REQUEST THE_REQUEST

The full HTTP request line sent by the browser to the server (eg, "GET /index.html HTTP/1.1"). 浏览器发送到服务器的完整HTTP请求行(例如,“ GET /index.html HTTP / 1.1”)。 This does not include any additional headers sent by the browser. 这不包括浏览器发送的任何其他标头。 This value has not been unescaped (decoded) , unlike most other variables below. 与以下大多数其他变量不同, 此值尚未被转义(解码)

Here is how your rule should look like 这是您的规则的样子

# 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]

Please note that you shouldn't be using relative path for internal rewrite, which could lead to confusion. 请注意,您不应该使用相对路径进行内部重写,否则可能导致混乱。 Instead, define a RewriteBase , use an absolute path or start from the domain root with a / . 而是定义一个RewriteBase ,使用绝对路径或以/开头的域根目录。

UPDATE UPDATE

Since you can have encoded forward slashes in your url, you need to set AllowEncodedSlashes to NoDecode (or On but it's unsafe). 由于您可以在网址中编码正斜杠,因此需要将AllowEncodedSlashes设置为NoDecode (或On但这是不安全的)。 Note also that, due to a bug, you must put this directive inside a virtual host context, even if the server config context is said to be OK (otherwise, it is simply ignored). 还要注意,由于存在错误,即使服务器配置上下文被认为是可以的,您也必须将该指令放在虚拟主机上下文中(否则,将被忽略)。 By default, AllowEncodedSlashes is set to Off . 默认情况下, AllowEncodedSlashes设置为Off So, Apache handles encoded slashes automatically by itself and refuses them, without passing the request to mod_rewrite . 因此,Apache自行自动处理编码的斜杠并拒绝它们,而无需将请求传递给mod_rewrite See the official documentation here . 请参阅此处的官方文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM