3C科技 娛樂遊戲 美食旅遊 時尚美妝 親子育兒 生活休閒 金融理財 健康運動 寰宇綜合

Zi 字媒體

2017-07-25T20:27:27+00:00
加入好友
惱人的 URL Encode/Decode 我們常在開發 Web 時,會發生連結失效 (404 Page not found.)、特別的參數值傳遞不正確、Query String 解譯錯誤等等問題或 Bug。追究之後常常都是忽略了 URL 編碼或者用了不正確的編碼所造成,看來我們需要多多認識 URL 的特性,順便養成「對 URL 敏感」的習慣。 URI 規範的歷史淵源 先來看看 URI 的歷史。最早在 1994 年 12 月,RFC 1738 起頭定義了 URI 最初的規範。經過了幾年的混亂與磨練,一直到了 1998 年 8 月才有了比較廣泛的標準,那就是 RFC 2396。而我們最常接觸的 RFC 2616 (也就是 HTTP 1.1) 在處理 URI 也是遵循 RFC 2396 標準,我們可以在規範看見以下描述: 3.2.3 URI Comparison Characters other than those in the "reserved" and "unsafe" sets (see RFC 2396 [42]) are equivalent to their ""%" HEX HEX" encoding. 但是後來隨著環境的演進,直到 2005 年 1 月所發佈的 RFC 3986 最終成為目前主流所實作的規範。因此以目前來說,採用 RFC 3986 是比較明智的選擇。 PHP urlencode() 與 rawurlencode() 的差異 先來測試一下: 1 2 3 4 5 6 7 8 9 <?php   $str='1+2&b and c';   echo urlencode($str); // show: 1+2&b+and+c   echo rawurlencode($str); // show: 1+2&b and c 發現了嗎?兩者在於對空白 (space) 的處理有不同的邏輯,根據官方文件描述 PHP 中的 urlencode() function 是遵循 application/x-www-form-urlencoded (就是我們常說的 Query String) 編碼規範,因此會把 space 空白變成 + 而不是   ,如下: urlencode differs from RFC 1738 by encoding spaces as + instead of 然而 PHP 中的 rawurlencode() function 是遵循 RFC 3986 進行實作,如下: Encodes the given string according to » RFC 3986. 由此看來使用 rawurlencode() 才是最推薦的方法,測試如下: JavaScript 中的 encodeURIComponent() 與 encodeURI() 的差異 JavaScript 測試如下: 1 2 3 4 5 6 7 8 9 <script type="text/javascript"> document.write(encodeURIComponent('1+2&b and c')); // show: 1+2&b and c </script>   <script type="text/javascript"> document.write(encodeURI('1+2&b and c')); // show: 1+2&b and c </script> 在 JavaScript 中,encodeURIComponent() 與 encodeURI() 差別在保留字 (不進行編碼的字元) 的定義不同: encodeURI() 的保留字為 ~!@#$&*()=:/,;?+' encodeURIComponent() 的保留字為 ~!*()' 此外 JavaScript 中的 encodeURIComponent() 也是遵循 RFC 3986 編碼,因此比較推薦採用這個函式。 討論 其實最混亂的就是 + 與 的問題,在 JavaScript 中所提供的 encodeURI() 並不是遵循 application/x-www-form-urlencoded 編碼規範,如果要在 JavaScript 環境下自行實作 application/x-www-form-urlencoded 編碼就必須先使用 encodeURIComponent() 轉換,然後再另外將 取代為 + 即可,如此就達到跟 PHP urlencode() 一樣的效果。 此外,我們在 Web 開發的過程中輸出 HTML 連結,雖然大多數瀏覽器都會很友善的自動對網址進行轉換再送出 HTTP Request 連線,但未了避免例外情況,我們還是遵循 RFC 3986 來處理 URL 比較正確,相容性也比較高。 參考資料 統一資源標誌符 URI Wiki RFC 1738 RFC 2396 RFC 3986 PHP: rawurlencode - Manual PHP: urlencode - Manual 分享到 Twitter(在新視窗中開啟) 按一下以分享至 Facebook(在新視窗中開啟) 分享到 LinkedIn(在新視窗中開啟) 點這裡寄給朋友(在新視窗中開啟) 按一下即可分享至 Skype(在新視窗中開啟) 分享到 Reddit(在新視窗中開啟) 分享到 Tumblr(在新視窗中開啟) 按一下以分享到 Telegram(在新視窗中開啟)

本文由toright提供 原文連結

寫了 5860316篇文章,獲得 23313次喜歡
精彩推薦