最近我有一个关于urlencode的奇怪问题,我碰巧在url的pathinfo和querystring部分都有一个“+”。
例如:
http://example.com/A + B?s=C + D
我在firefox中使用tamperdata,可以确保thafox firefox已经将url编码为以下内容:
http://example.com/A%20+%20B?s=C%20+%20D
而在服务器端,我有Apache的URL重写启用以下指令:
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !=/favicon.ico RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
然后,在PHP中,我得到了以下几点:
$_REQUEST['q'] = 'A B'; $_REQUEST['s'] = 'C D'; $_SERVER['QUERY_STRING'] = 'q=A + B&s=C%20+%20D';
正如我们所知,php会自动使用urldecode来将查询stringparese到$ _REQUEST超级variables,这就解释了为什么'A + B'变成了'AB','C + D'变成了'C D''。 url重写必须解码所有的字符才能进行rewirte映射。 FLAG B将有助于在映射后将其重新映射。所以重写规则变成了跟随着B FLAG的应用。
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !=/favicon.ico RewriteRule ^(.*)$ index.php?q=$1 [B,L,QSA]
然后,成果变成:
$_REQUEST['q'] = 'A + B'; $_REQUEST['s'] = 'C D'; $_SERVER['QUERY_STRING'] = 'q=A+%2B+B&s=C%20+%20D';
我期望的是:
$_SERVER['QUERY_STRING'] = 'q=A%20+%20B&s=C%20+%20D';
然后,我可以使用rawurldecode mannullyparsing下面的查询string,这也是firefox本来的
$_REQUEST['q'] = 'A + B'; $_REQUEST['s'] = 'C + D';
但是相反,apache mod-rewrite B glag让q变成了'A +%2B + B',它与原始的firefox编码'A%20 +%20B'不同。当然,apache的编码与php urlencode函数兼容。
所以问题是为什么Firefox和Apache的行为如此不同?为什么firefox不会编码'A + B'为'A +%2B + B'作为常用,但'A%20 +%20'导致这么多不兼容的PHP和服务器端?