Apache mod_rewrite%2B和加号(+)符号

时间:2010-03-26 13:23:43

标签: apache mod-rewrite

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

遵守以下规则..

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

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

如果我使用“B”标志,那么在两种情况下,+符号都会转换为%2B,并且应用程序最终会出现相同的问题但反转(空格和加号都是加号)

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

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

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

不,这与引用的问题不完全相同。这里的问题特别是加号和Apache: mod_rewrite: Spcaes & Special Characters in URL not working的答案没有解决这个问题。

斜杠也存在问题,请参阅http://httpd.apache.org/docs/current/mod/core.html#allowencodedslashes (但你确实需要访问Apache配置来执行此操作 - .htaccess不会这样做。)

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

的文件
  

“a b.html”。

加号通过PHP解码为查询字符串的$ _GET数组(或任何相关的语言机制),因为浏览器中的表单处理程序将它们放入。所以Apache会在应用重写之前将%2B转换为+,并留下+本身,这意味着你无法分辨出来。

当然,人们可能会争辩说,用作空间的+在这些网址中只是无效,而且只能使用%20。但是,如果你无法控制生成它们,你一定会看到它们。浏览器不会自动生成它们。

答案是DIY,在许多方面它更可预测和更简单:

  

RewriteRule。* index.php [L]

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

然后在index.php

  

$ uri = substr($ _ SERVER ['REQUEST_URI'],1); //删除前导斜杠

     

$ qmpos = strpos($ uri,'?'); //是否有问号,如果有的话

     

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

     

$ decoding = urldecode($ uri); //解码URL

之前的部分      

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

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

我认为这适用于空网址(http://example.com/)或仅包含查询字符串(http://example.com/?foo=1)的网址,以及简单大小写(http://example.com/bar)和案例还有一个查询字符串(http://example.com/bar?foo=1)。毫无疑问,类似的方法适用于其他语言。

在您的特定情况下,您实际上根本不希望在PHP中解码这些优点。没关系,请使用rawurldecode,而不是使用rawurldecode。