Chinaunix首页 | 论坛 | 博客
  • 博客访问: 88721
  • 博文数量: 24
  • 博客积分: 2396
  • 博客等级: 上尉
  • 技术积分: 205
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-28 18:36
文章分类

全部博文(24)

文章存档

2011年(14)

2010年(10)

分类: Python/Ruby

2010-12-02 16:51:26

至如ericsk者,國四無雙发表于2010-11-25 14:23:05

因為噗浪朋友的一則訊息,讓我興起了想要整理一些關於 URLEncode 的問題,整理一下才發現每個語言都有不同的函式來處理關於 URLEncode 的問題。

先說為什麼需要作 URLEncode,RFC 3986規範了哪些字元是作為保留字(如:!、@、/、?等),如果URL中使用到了這些保留字,就必須將它編碼為「%HEXHEX」的形式,舉例來說,「空白字元」的 ASCII code 是32,所以會被編碼為 %20,而其它 non-ASCII 字元(如:中文字)則以 UTF-8 字元編碼後的位元組來編碼成 %HEXHEX 的形式。

如果有一個字串是:「This is my **書本**」,根據 RFC 3986 的定義,作完 URL encode 之後應該會變成「This%20is%20my%20%2A%2A%E6%9B%B8%E6%9C%AC%2A%2A」。

那什麼時候會需要對文字作 URL encode 呢?比方說,Facebook 提供了一個分享網頁到個人塗鴨牆(Wall)的作法,那就是將欲分享的網頁URL,比方說是 http://www.example.com/,只要將它作為參數(u傳給http://www.facebook.com/share.php就可以了,但你千萬不能寫成:

http://www.facebook.com/share.php?u=http://www.example.com/

,而是必須將它作 URL encode 之後,組合成:

http://www.facebook.com/share.php?u=http%3A%2F%2Fwww.example.com%2F

這樣才是正確的。

若是你在瀏覽器的網址列直接輸入前者也會正確,那是因為瀏覽器會幫你作了 url encode

不過,在 RFC 3986 之前,HTTP 也有為 GET/POST 在傳遞參數時的 url encode 方式作定義,基本上也是 encode 成 %HEXHEX 的形式,保留字跟 RFC 3986 的有部份出入,不過就沒有限定一定是 UTF-8 的文字編碼了,而且還有一個重點--「空白字元」會被編碼成 + 而不是 %20。所以「This is a book」就會被編碼成「This+is+a+book」。

常用語言的函式庫

因為有這樣的差異,所以開發人員在使用函式庫的時候常常會搞混什麼時候該用/不該用什麼函式,以 PHP 來說就分為兩組函式:

  • urlencode / urldecode

    簡單地說就是以 HTTP 所使用的 application/x-www-form-urlencoded 的編碼規則,也就是會將空白字元編碼成 + 而不是%20。

  • rawurlencode / rawurldecode

    按照 RFC 3986 所定義的方式來作編碼。

Python 版本的話就是:

  • urllib.urlencode / urllib.urldecode

    會把空白字元編碼成 +

  • 目前要使用 Python 3 以後的 urllib.parse.urlencode 才會按照 RFC 3986 的方式來作編碼,若是 2.x 的版本就要另外處理或是找 3rd-party 資料庫來做。

JavaScript 的 encodeURI 或是 encodeURIComponent (兩者僅相差一些保留字是否要作編碼,如 #)目前則是都使用 RFC 3986 的方式來作編碼,所以要作 application/x-www-form-urlencoded 的編碼時(AJAX POST),就要自己把 %20 替換成 + (jQuery 目前的程式碼就是這樣做的)

Java 的 java.net.URLEncoder.encode 這個 method 也是編碼成 application/x-www-form-urlencoded 的方式,如果要遵照 RFC 3986 的定義,則可以自行再把 + 替換成 %20 即可。

阅读(646) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~