發現如今幾乎全部的網站都對url中的漢字和特殊的字符,進行了urlencode操做,也就是:javascript
http://hi.baidu.com/%BE%B2%D0%C4%C0%CF%C8%CB/creat/blog/php
這個樣子,中間%形式的,確定就是個人登陸用戶名稱了吧。html
爲何對這些字符進行了u的編碼形式,是爲了字符編碼(gbk、utf8)仍是爲了避免出現特殊的字符在url中?都知道要轉,可是轉了的真正好處呢。查看了網上的不少資料,也沒有找到更加準確的說法。前端
url轉義其實也只是爲了符合url的規範而已。由於在標準的url規範中中文和不少的字符是不容許出如今url中的。java
看一下php的urlencode的說明了。apache
urlencode — 編碼 URL 字符串瀏覽器
<div u"="">返回字符串,此字符串中除了 -_. 以外的全部非字母數字字符都將被替換成百分號(%)後跟兩位十六進制數,空格則編碼爲加號(+)。此編碼與 WWW 表單 POST 數據的編碼方式是同樣的,同時與 application/x-www-form-urlencoded 的媒體類型編碼方式同樣。因爲歷史緣由,此編碼在將空格編碼爲加號(+)方面與 RFC1738 編碼(參見 rawurlencode())不一樣。此函數便於將字符串編碼並將其用於 URL 的請求部分,同時它還便於將變量傳遞給下一頁。tomcat
標準的英文說明是:安全
"...Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()," [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL."
那哪些字符是須要轉化的呢?服務器
1. ASCII 的控制字符
這些字符都是不可打印的,天然須要進行轉化。
2. 一些非ASCII字符
這些字符天然是非法的字符範圍。轉化也是理所固然的了。
3. 一些保留字符
很明顯最多見的就是「&」了,這個若是出如今url中了,那你認爲是url中的一個字符呢,仍是特殊的參數分割用的呢?
4. 就是一些不安全的字符了。
例如:空格。爲了防止引發歧義,須要被轉化爲「+」。
明白了這些,也就知道了爲何須要轉化了,而轉化的規則也是很簡單的。
按照每一個字符對應的字符編碼,不是符合咱們範圍的,通通的轉化爲%的形式也就是了。天然也是16進制的形式。
和字符編碼無關
經過urlencode的轉化規則和目的,咱們也很容易的看出,urleocode是基於字符編碼的。一樣的一個漢字,不一樣的編碼類型,確定對應不一樣的urleocode的串。gbk編碼的有gbk的encode結果。
apache等服務器,接受到字符串後,能夠進行decode,可是仍是沒法解決編碼的問題。編碼問題,仍是須要靠約定或者字符編碼的判斷解決。
所以,urleocode只是爲了url中一些非ascii字符,能夠正確無誤的被傳輸,至於使用哪一種編碼,就不是eocode所關心和解決的問題了。
編碼問題,不是urlencode所要解決的。
轉自:http://apps.hi.baidu.com/share/detail/32230450
參考資料:
http://www.blooberry.com/indexdot/html/topics/urlencoding.htm
form有2中方法把數據提交給服務器,get和post,分別說下吧。
(一)get提交
1.首先說下客戶端(瀏覽器)的form表單用get方法是如何將數據編碼後提交給服務器端的吧。
對於get方法來講,都是把數據串聯在請求的url後面做爲參數,如:http://localhost:8080/servlet?msg=abc
(很常見的一個亂碼問題就要出現了,若是url中出現中文或其它特殊字符的話,如:http://localhost:8080/ /servlet?msg=杭州,服務器端容易獲得亂碼),url拼接完成後,瀏覽器會對url進行URL encode,而後發送給服務器,URL encode的過程就是把部分url作爲字符,按照某種編碼方式(如:utf-8,gbk等)編碼成二進制的字節碼,而後每一個字節用一個包含3個字符的字符串 "%xy" 表示,其中xy爲該字節的兩位十六進制表示形式。我這裏說的可能不清楚,
具體介紹能夠看下java.net.URLEncoder類的介紹在這裏。瞭解了 URL encode的過程,咱們能看到2個很重要的問題,第一:須要URL encode的字符通常都是非ASCII的字符(籠統的講),再通俗的講就是除了英文字母之外的文字(如:中文,日文等)都要進行URL encode,因此對於咱們來講,都是英文字母的url不會出現服務器獲得亂碼問題,出現亂碼都是url裏面帶了中文或特殊字符形成的;第二:URL encode到底按照那種編碼方式對字符編碼?這裏就是瀏覽器的事情了,並且不一樣的瀏覽器有不一樣的作法,中文版的瀏覽器通常會默認的使用GBK,經過設置瀏覽器也可使用UTF-8,可能不一樣的用戶就有不一樣的瀏覽器設置,也就形成不一樣的編碼方式,因此不少網站的作法都是先把url裏面的中文或特殊字符用 javascript作URL encode,而後再拼接url提交數據,也就是替瀏覽器作了URL encode,好處就是網站能夠統一get方法提交數據的編碼方式。 完成了URL encode,那麼如今的url就成了ASCII範圍內的字符了,而後以iso-8859-1的編碼方式轉換成二進制隨着請求頭一塊兒發送出去。這裏想多說幾句的是,對於get方法來講,沒有請求實體,含有數據的url都在請求頭裏面,之因此用URL encode,我我的覺的緣由是:對於請求頭來講最終都是要用iso-8859-1編碼方式編碼成二進制的101010.....的純數據在互聯網上傳送,若是直接將含有中文等特殊字符作iso-8859-1編碼會丟失信息,因此先作URL encode是有必要的。
2。服務器端(tomcat)是如何將數據獲取到進行解碼的。
第一步是先把數據用iso-8859-1進行解碼,對於get方法來講,tomcat獲取數據的是ASCII範圍內的請求頭字符,其中的請求url裏面帶有參數數據,若是參數中有中文等特殊字符,那麼目前仍是URL encode後的%XY狀態,先停下,咱們先說下開發人員通常獲取數據的過程。一般你們都是request.getParameter("name")獲取參數數據,咱們在request對象或得的數據都是通過解碼過的,而解碼過程當中程序裏是沒法指定,這裏要說下,有不少新手說用 request.setCharacterEncoding("字符集")能夠指定解碼方式,實際上是不能夠的,看servlet的官方API說明有對此方法的解釋:Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader().能夠看出對於get方法他是無能爲力的。那麼到底用什麼編碼方式解碼數據的呢,這是tomcat的事情了,默認缺省用的是 iso-8859-1,這樣咱們就能找到爲何get請求帶中文參數爲何在服務器端獲得亂碼了,緣由是在客戶端通常都是用UTF-8或GBK對數據 URL encode,這裏用iso-8859-1方式URL decoder顯然不行,在程序裏咱們能夠直接
Java代碼
1. new String(request.getParameter("name").getBytes("iso-8859-1"),"客戶端指定的URL encode編碼方式")
還原回字節碼,而後用正確的方式解碼數據,網上的文章一般是在tomcat裏面作個配置
Xml代碼
1. <Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" URIEncoding="GBK"/>
這樣是讓tomcat在獲取數據後用指定的方式URL decoder,URL decoder的介紹在這裏
http://blog.csdn.net/vickyway/article/details/46375971
http://www.jb51.net/article/80181.htm
(二)post提交
1.客戶端(瀏覽器)的form表單用post方法是如何將數據編碼後提交給服務器端的。
在post方法裏所要傳送的數據也要URL encode,那麼他是用什麼編碼方式的呢?
在form所在的html文件裏若是有段<meta http-equiv="Content-Type" content="text/html; charset=字符集(GBK,utf-8等)"/>,那麼post就會用此處指定的編碼方式編碼。通常你們都認爲這段代碼是爲了讓瀏覽器知道用什麼字符集來對網頁解釋,因此網站都會把它放在html代碼的最前端,儘可能不出現亂碼,其實它還有個做用就是指定form表單的post方法提交數據的 URL encode編碼方式。從這裏能夠看出對於get方法來數,瀏覽器對數據的URL encode的編碼方式是有瀏覽器設置來決定,(能夠用js作統一指定),而post方法,開發人員能夠指定。
2。服務器端(tomcat)是如何將數據獲取到進行解碼的。
若是用tomcat默認缺省設置,也沒作過濾器等編碼設置,那麼他也是用iso-8859-1解碼的,可是request.setCharacterEncoding("字符集")能夠派上用場。
我發現上面說的tomcat所作的事情前提都是在請求頭裏沒有指定編碼方式,若是請求頭裏指定了編碼方式將按照這種方式編碼。
有2篇文章推薦下,地址分別是
深刻淺出URL編碼:http://www.cnblogs.com/yencain/articles/1321386.html;
表單用post方法提交數據時亂碼問題:http://wanghuan8086.javaeye.com/blog/173869
用post很重要的在form所在的html文件裏若是有段<meta http-equiv="Content-Type" content="text/html; charset=字符集(GBK,utf-8等)"/>
強烈建議使用post提交