Apache mod_rewrite %2B 和加号 (+) [英] Apache mod_rewrite %2B and plus (+) signs

查看:38
本文介绍了Apache mod_rewrite %2B 和加号 (+)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 apache/mod_rewrite 来重写 URL,但我在使用加号时遇到问题.

I'm using apache / mod_rewrite to re-write URLs but I am having problems with the plus sign.

以下规则..

RewriteRule ^/(.+[^/])/?$ http://localhost:8080/app/home?tag=$1 [P,L] 

两者:

http://localhost/1+1 and http://localhost/1%2B2

最终变成

uri=http://localhost:8080/app/home, args=tag=1+2

因此,在这两种情况下,应用程序都将加号转换为空格,因此它无法再区分空格和加号.

So in both cases the application translates the plus sign into a space so it cannot differentiate between spaces and plus signs anymore.

如果我使用 "B" 标志,那么在这两种情况下,+ 号都会被转换为 %2B,应用程序最终会遇到同样的问题,但相反(空格和加号都是加号)

If I use the "B" flag, then in both cases the + signs are translated into %2B and the application ends up with the same problem but reversed (both spaces and plus signs are plus signs)

有没有办法让 apache 正确地将 %2B 转义为加号而不是空格?

Is there a way to get apache to properly escape %2B into a plus sign and not a space?

我阅读了一些关于 mod_security 的内容,但我没有使用它,所以我不确定是否有其他一些安全机制导致了这种情况?

I read something about mod_security but I am not using that so I am not sure if there is some other security mechanism that is causing this?

任何帮助将不胜感激!

推荐答案

不,这与引用的问题不太一样.这里的问题特别是加号和 Apache 的答案: mod_rewrite: Spcaes &URL 中的特殊字符不起作用 不能解决这个问题.

No, this isn't quite the same as the referenced question. The problem here is specifically plus signs and the answer to Apache: mod_rewrite: Spcaes & Special Characters in URL not working doesn't address that.

斜线也有问题,参见 http:///httpd.apache.org/docs/current/mod/core.html#allowencodedslashes(但您确实需要访问 Apache 配置才能执行此操作 - .htaccess 不会这样做).

There's also an issue with slashes, for which see http://httpd.apache.org/docs/current/mod/core.html#allowencodedslashes (but you do need access to the Apache config to do this - .htaccess won't do).

事实上,单独使用重写规则不可能.Apache 在通过重写之前对 URL 进行解码,它不理解加号:http://example.com/a+b.html 不会提供名为

In fact it is impossible to do using a rewrite rule alone. Apache decodes the URL before putting it through rewrite, but it doesn't understand plus signs: http://example.com/a+b.html wouldn't deliver a file called

a b.html".

加号被 PHP 解码为 $_GET 数组(或任何相关的语言机制)用于查询字符串,因为浏览器中的表单处理程序将它们放入.因此 Apache 将在应用重写之前将 %2B 转换为 +,并且不理会 + 本身,这意味着您无法分辨其中的区别.

The plus signs are decoded by PHP into the $_GET array (or whatever the relevant language mechanism is) for query strings, because form handlers in browsers put them in. So Apache will translate %2B to + before applying the rewrite, and leave + itself alone, meaning you can't tell the difference.

当然,有人可能会争辩说,在此类 URL 中用作空格的 + 是无效的,应该仅使用 %20.但是,如果您无法控制生成它们,那么您一定会看到它们.不过浏览器不会自动生成它们.

Of course, one could argue that + used as space is simply invalid in such URLs and one should use only %20. However, if you don't have control over generating them, you're bound to see them. Browsers won't generate them automatically though.

答案是 DIY,而且在很多方面它更容易预测和更简单:

The answer is DIY, and in many ways it is more predictable and simpler:

RewriteRule .* index.php [L]

RewriteRule .* index.php [L]

因此一切都变成了 index.php 并且没有尝试构造查询字符串.如果您想排除某些模式,例如那些带有斜线的文件,或者确实存在明确文件的地方,明显的修改适用.例如RewriteCond %{REQUEST_FILENAME} !-f

Hence everything turns into index.php and there's no attempt to construct a query string. If you want to exclude certain patterns, e.g. those with slashes in, or where an explicit file does exist, the obvious amendments apply. e.g. RewriteCond %{REQUEST_FILENAME} !-f

然后在 index.php

Then in index.php

$uri = substr($_SERVER['REQUEST_URI'], 1);//去掉前导斜线

$uri = substr($_SERVER['REQUEST_URI'], 1); // remove leading slash

$qmpos = strpos($uri, '?');//是否有问号,如果有,在哪里

$qmpos = strpos($uri, '?'); // is there a question mark, if so where

if ($qmpos !== FALSE) { $uri = substr($uri, 0, $qmpos);}//只有 q.m. 之前的位

if ($qmpos !== FALSE) { $uri = substr($uri, 0, $qmpos); } // only the bit before q.m.

$decoded = urldecode($uri);//解码 URL 前的部分

$decoded = urldecode($uri); // decode the part before the URL

if (!empty($decoded)) { $_GET['args'] = $decoded;}//将结果添加到 $_GET

if (! empty($decoded)) { $_GET['args'] = $decoded; } // add result to $_GET

原始请求进行解码(不包括前导斜杠 - 如果您在层次结构的更深处会略有不同,但原理是相同的 - 并且不包括任何其他查询字符串),以及根据 PHP 的正常规则解码 args 参数并将其放入 $_GET 中,以便您可以按照通常的方式将其与其余的 $_GET 查询字符串参数一起处理.

That decodes the original request (excluding the leading slash - would be slightly different if you're deeper down a hierarchy, but the principle is the same - and excluding any additional query string), and decodes the args parameter according to PHP's normal rules and puts it into $_GET so you can process it along with the rest of the $_GET query string parameters in the usual way.

我相信这应该适用于空网址(http://example.com/)或那些只有一个查询字符串(http://example.com/?foo=1),以及作为简单的情况(http://example.com/bar)和带有查询字符串的情况(http://example.com/bar?foo=1).毫无疑问,类似的方法适用于其他语言.

I believe this should work for empty URLs (http://example.com/) or those which only have a query string (http://example.com/?foo=1), as well as the simple case (http://example.com/bar) and the case with a query string as well (http://example.com/bar?foo=1). No doubt similar approaches will work for other languages.

在您的特定情况下,您实际上根本不希望在 PHP 中解码加号.没关系,改用 rawurldecode,它没有好处.

In your particular case, you actually don't want the pluses decoded in the PHP at all. That's fine, use rawurldecode instead, which doesn't do pluses.

这篇关于Apache mod_rewrite %2B 和加号 (+)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆