get提交
一、客戶端(瀏覽器)的form表單用get方法是如何將數據編碼后提交給服務器端的?
1、對於get方法來說,都是把數據串聯在請求的url后面作為參數,如:http://localhost:8080/servlet?msg=abc
2、很常見的一個亂碼問題就要出現了,如果url中出現中文或其它特殊字符的話,如:http://localhost:8080/ /servlet?msg=杭州,服務器端容易得到亂碼。
3、url拼接完成后,瀏覽器會對url進行URL encode,然后發送給服務器。URL encode的過程就是把部分url作為字符,按照某種編碼方式(如:utf-8,gbk等)編碼成二進制的字節碼,然后每個字節用一個包含3個字符的字 符串 "%xy" 表示,其中xy為該字節的兩位十六進制表示形式。
4、了解了 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的編碼方式轉換成二進制隨着請求頭一起發送出去。
5、對於get方法來說,沒有請求實體,含有數據的url都在請求頭里面。
之所以用URL Encode,我個人覺的原因是:對於請求頭來說最終都是要用ISO-8859-1編碼方式編碼成二進制的101010.....的純數據在互聯網上傳 送,如果直接將含有中文等特殊字符做iso-8859-1編碼會丟失信息,所以先做URL encode是有必要的。
總結:
使用請求方法get時,如果數據串聯后的url中只有英文字母或數字,在進行url編碼的時候可以直接編碼為可以在網絡中傳輸的二進制字節碼數據。
但是如果數據串聯后的url中還存在有除英文字母以外的文字(如中文,日文等),在進行url編碼的時候就需要將這些除英文字母以外的文字進行url編碼編碼為ASCII碼,然后再將這些ASCII碼繼續編碼為可以在網絡中傳輸的二進制字節碼數據。
二、服務端(服務器)是如何將數據獲取到進行解碼的
1、第一步是先把瀏覽器發送過來的數據用ISO-8859-1編碼方式進行解碼。
2、對於get方法來說,服務器對數據進行解碼之后得到的是ASCII范圍內的請求頭字符【也就是上述講解的瀏覽器在發送數據時對url進行url Encode之后的狀態】,其中的請求url里面帶有參數數據,如果參數中有中文等特殊字符,那么目前還是URL Encode后的%XY狀態。
3、那么到底用什么編碼方式解碼數據的呢?其實這取決於服務器,默認缺省用的是 ISO-8859-1,這就能找到為什么get請求帶中文參數為什么在服務器端得到亂碼了,原因是在客戶端一般都是用UTF-8或GBK對數據 URL Encode,這里用ISO-8859-1方式URL Decode顯然不行。通常還需要在服務器中配置正確的方式解碼數據:先使用ISO-8859-1方式對接收到的數據進行二進制解碼,此時得到是可能存在“%xy”形式的ASCII碼,在對url Decode,解析成正確的除英文字母以外的其他文字。
post提交
一、客戶端(瀏覽器)的form表單用post方法是如何將數據編碼后提交給服務器端的?
1、在post方法里所要傳送的數據也要URL encode,那么他是用什么編碼方式的呢?
在form表單所在的html文件里如果有一段代碼:
<meta http-equiv="Content-Type" content="text/html; charset=字符集(GBK,utf-8等)"/>
post請求方法時就會用此處(charset字段)指定的編碼方式編碼。
一般大家都認為這段代碼是為了讓瀏覽器知道用什么字符集來對網頁解釋,所以網站都會把它放在html代碼的最前端,盡量不出現亂碼。其實它還有個作用就是指定form表單的post方法提交數據的 URLencode編碼方式。
2、從這里可以看出對於get請求方法來說,瀏覽器對數據的URL Encode的編碼方式取決於瀏覽器的設置(可以用js做統一指定);而對於post請求方法來說,開發人員可以指定對數據的編碼方式。
二、服務端(服務器)是如何將數據獲取到進行解碼的
如果用tomcat默認缺省設置,也沒做過濾器等編碼設置,那么他也是用iso-8859-1解碼的【將二進制字節碼數據解碼為瀏覽器發送的數據】,但是request.setCharacterEncoding("字符集")可以派上用場。
總結: