php中urlencode與rawurlencode的區別

前段時間說本身遇到了個《URL加號引起錯誤》的BUG,引發這個bug的緣由就是本身在URL中使用了 urlencode 函數,該函數會把空格轉換成加號,這樣就致使URL解析出錯,而空格只有轉換成 %20 才能夠能夠正常解析,這時咱們就須要使用 rawurlencode 函數。下面就介紹一下 urlencode 函數與 rawurlencode 函數的區別:php

urlencode 函數:安全

返回字符串,此字符串中除了 -_. 以外的全部非字母數字字符都將被替換成百分號(%)後跟兩位十六進制數,空格則編碼爲加號(+)。此編碼與 WWW 表單 POST 數據的編碼方式是同樣的,同時與 application/x-www-form-urlencoded 的媒體類型編碼方式同樣。因爲歷史緣由,此編碼在將空格編碼爲加號(+)方面與 RFC1738 編碼(參見 rawurlencode())不一樣。服務器

rawurlencode 函數:app

返回字符串,此字符串中除了 -_. 以外的全部非字母數字字符都將被替換成百分號(%)後跟兩位十六進制數。這是在 » RFC 3986 中描述的編碼,是爲了保護原義字符以避免其被解釋爲特殊的 URL 定界符,同時保護 URL 格式以避免其被傳輸媒體(像一些郵件系統)使用字符轉換時弄亂。下面咱們來看一下例子:函數

 代碼以下 複製代碼

<?php編碼

$string = "hello world";url

echo urlencode($string) . '<br/>'; //輸出:hello+world
echo rawurldecode($string) . '<br/>';//輸出:hello%20worldspa

?>.net

具體例子比較:code

 代碼以下 複製代碼

<?php
for ($i = 0x20; $i < 0x7f; $i++) {
$str .= dechex($i);
}

$asscii = pack("H*",$str);
echo "全部的可打印的asscii字符:(從空格到~)n". $asscii."\n";
echo "urlencode 的結果:\n".urlencode($asscii);
echo "\n";
echo "urlencode 不作編碼的字http://www.111cn.net/符:\n".preg_replace("/%.{2}/","",urlencode($asscii));
echo "\n";
echo "rawurlencode 的結果:\n".rawurlencode($asscii);
echo "\n";
echo "rawurlencode 不作編碼的字符:\n".preg_replace("/%.{2}/","",rawurlencode($asscii));
echo  "\n";

exit;
?>

輸出結果:
———————————————————————————
全部的可打印的asscii字符:(從空格到~)
!"#$%&’()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~
urlencode 的結果:
+%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E
urlencode 不作編碼的字符:
+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz
rawurlencode 的結果:
%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E
rawurlencode 不作編碼的字符:
-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz

---------------------------------------------------------------------------------
比較兩者的結果:
1.  數字、大小寫字母都不編碼
2.  減號、點號、下劃線  三個不編碼
3. rawurlencode比urlencode多編碼一個」加號「

關於JavaScript中escape與encodeURIComponent的區別:

 代碼以下 複製代碼

>>>  console.log(encodeURIComponent("統一註冊1"));

%E7%BB%9F%E4%B8%80%E6%B3%A8%E5%86%8C1
>>> console.log(escape("統一註冊1"));
%u7EDF%u4E00%u6CE8%u518C1

<?php
echo iconv("utf-8","gbk",urldecode("%E7%BB%9F%E4%B8%80%E6%B3%A8%E5%86%8C1"));
echo "\n";
echo urldecode("%u7EDF%u4E00%u6CE8%u518C1");
// 使用下面的unescape能夠
//echo iconv("utf-8","gbk",unescape("%u7EDF%u4E00%u6CE8%u518C1");
exit;
?>

輸出結果:
======================================
統一註冊1
%u7EDF%u4E00%u6CE8%u518C1
======================================

結果說明:
1. encodeURIComponent 老是把輸入轉換成utf8編碼處理的,按字節編碼
2. escape是按照unicode編碼處理的,由於它也對url中不安全的字符作了編碼,因此也能夠在url中作編碼使用,可是,服務器端不會自動解碼,下面提供一個PHP版的解碼函數,是用手冊裏找的:

<?php

 代碼以下 複製代碼

function unescape($str) {
    $str = rawurldecode($str);
    preg_match_all("/(?:%u.{4})|&#x.{4};|&#d+;|.+/U",$str,$r);
    $ar = $r[0];
    foreach($ar as $k=>$v) {
        if(substr($v,0,2) == "%u")
            $ar[$k] = iconv("UCS-2","UTF-8",pack("H4",substr($v,-4)));
        elseif(substr($v,0,3) == "&#x")
            $ar[$k] = iconv("UCS-2","UTF-8",pack("H4",substr($v,3,-1)));
        elseif(substr($v,0,2) == "&#") {
            $ar[$k] = iconv("UCS-2","UTF-8",pack("n",substr($v,2,-1)));
        }
    }
    return join("",$ar);
}

?>

 

>>> console.log(escape(" !\"#$%&'()*+,-./0123456789:;=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~"));
%20%21%22%23%24%25%26%27%28%29*+%2C-./0123456789%3A%3B%3C%3D%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D%7E
>>> console.log(encodeURIComponent("!\"#$%&’()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~"));
%20!%22%23%24%25%26'()*%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~
>>> console.log(escape("!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~").replace(/%.{2}/g,""));

*+-./0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz
>>> console.log(encodeURIComponent("!\"#$%&’()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~").replace(/%.{2}/g,""));
!’()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~

結果比較:
escape未編碼的字符: *+-./@_   共7個
encodeURIComponent未編碼的字符: !’()*-._~  共9個

來自:http://www.111cn.net/phper/php-cy/58640.htm

相關文章
相關標籤/搜索