前段時間說自己遇到了個《URL加號引發錯誤》的BUG,引起這個bug的原因就是自己在URL中使用了 urlencode 函數,該函數會把空格轉換成加號,這樣就導致URL解析出錯,而空格只有轉換成 %20 才可以可以正常解析,這時我們就需要使用 rawurlencode 函數。
下面就介紹一下 urlencode 函數與 rawurlencode 函數的區別:
urlencode 函數:
返回字符串,此字符串中除了 -_. 之外的所有非字母數字字符都將被替換成百分號(%)後跟兩位十六進制數,空格則編碼為加號(+)。此編碼與 WWW 表單 POST 數據的編碼方式是一樣的,同時與 application/x-www-form-urlencoded 的媒體類型編碼方式一樣。由於歷史原因,此編碼在將空格編碼為加號(+)方面與 RFC1738 編碼(參見 rawurlencode())不同。
rawurlencode 函數:
返回字符串,此字符串中除了 -_. 之外的所有非字母數字字符都將被替換成百分號(%)後跟兩位十六進制數。這是在 » RFC 3986 中描述的編碼,是為了保護原義字符以免其被解釋為特殊的 URL 定界符,同時保護 URL 格式以免其被傳輸媒體(像一些郵件系統)使用字符轉換時弄亂。下面我們來看一下例子:
<?php $string = "hello world"; echo urlencode($string) . '<br/>'; //輸出:hello+world echo rawurldecode($string) . '<br/>';//輸出:hello%20world ?>
具體例子比較:
<?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.bkjia.com/符:\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})|.{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) == "") $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個
以上這篇淺談php中urlencode與rawurlencode的區別就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持幫客之家。