1. 程式人生 > >GET&&POST請求編碼過程

GET&&POST請求編碼過程

指定編碼 -c 添加 由於 有一個 代理服務器 action nco time

編碼、解碼

  我們在開發過程中不可避免的一個話題就是編碼和解碼,那麽什麽是編碼什麽是解碼呢?為什麽要進行編碼和解碼呢?下面我們一一分析!

編碼和解碼的概念

  編碼是信息從一種形式或格式轉換為另一種形式的過程也稱為計算機編程語言的代碼簡稱編碼。用預先規定的方法將文字、數字或其它對象編成數碼,或將信息、數據轉換成規定的電脈沖信號。編碼在電子計算機、電視、遙控和通訊等方面廣泛使用。編碼是信息從一種形式或格式轉換為另一種形式的過程。解碼,是編碼的逆過程。例如:“我是中國人!”按照UTF-8編碼後為我是中国人!

為什麽要進行編碼和解碼

  我們每逢談到編碼的時候都避不開中文的編解碼問題,但是為什麽中文要進行編解碼呢,可不可以不進行編解碼呢?要回答這個問題,必須要回答計算機是如何表示我們人類所能夠理解的符號的,這些符號也就是我們人類所使用的語言。由於人類的語言太多,表示這些語言的符號太多,無法用計算機中的一個基本存儲單元-----字節(byte)來表示,因而必須要經過拆分或一些翻譯工作,才能讓計算機理解我們的語言。我們可以把計算機能夠理解的語言假定為英語,其他語言要能夠在計算機中使用,必須得經過一次翻譯,把它翻譯成英語。這個翻譯的過程就稱之為編碼。所以可以想象,只要不是說英語的國家,要使用計算機就必須經過編碼。這看起來有些霸道,但這就是現狀。這也和我國現在大力推廣漢語一樣,希望其他國家都會說漢語,以後其他語言都會被翻譯成漢語,我們可以把在計算機中存儲信息的最小單位改成漢字,這樣就不存在編碼問題了。

  所以總起來說,編碼的原因可以總結為一下幾條:

  1. 在計算機中存儲信息的最小單位是一個字節,即8bit,所以能表示的字符範圍是0-255個。【即可以做個比方:比如0000 0007 用來代表一個字符‘我’,那麽1byte就只能最多用來表示255個字符】
  2. 人類要表示的字符太多,無法用一個字節來完全表示【漢字遠遠超出255個】

要解決這個矛盾必須要有一個新的數據結構char,而從char到byte必須經過編碼。

GET和POST請求的編碼過程

  我們在處理用戶請求的時候處理最多的請求方式就是GET和POST請求,相對來說處理編碼問題也多在這兩種請求上,下面我們就來看一下這兩種請求的編碼過程,不過在了解編碼過程之前我們先來看一下兩種請求方式的比較;【多一嘴:Http定義了與服務器交互的不同方法,最基本的方法有4種,分別是GET,POST,PUT,DELETE。URL全稱是資源描述符,我們可以這樣認為:一個URL地址,它用於描述一個網絡上的資源,而HTTP中的GET,POST,PUT,DELETE就對應著對這個資源的查,改,增,刪4個操作。到這裏,大家應該有個大概的了解了,GET一般用於獲取/查詢資源信息,而POST一般用於更新資源信息。】

1、Get是用來從服務器上獲得數據(沒有請求體,用於請求查詢,參數在URL中),而Post是用來向服務器上傳遞數據(包含請求體)。

2、Get將表單中數據的按照variable=value的形式,添加到action(服務)所指向的URL後面,並且兩者使用“?”連接,而各個變量之間使用“&”連接;Post是將表單中的數據放在form的數據體中,按照變量和值相對應的方式,傳遞到action所指向URL。

3、Get是不安全的,因為在傳輸過程,數據被放在請求的URL中,而如今現有的很多服務器、代理服務器或者用戶代理都會將請求URL記錄到日誌文件中,然後放在某個地方,這樣就可能會有一些隱私的信息被第三方看到。另外,用戶也可以在瀏覽器上直接看到提交的數據,一些系統內部消息將會一同顯示在用戶面前。Post的所有操作對用戶來說都是不可見的。

4、Get傳輸的數據量小,因為受URL長度限制GET方式提交的數據最多只能是1024字節;Post可以傳輸大量的數據(理論上數據大小沒有限制),所以在上傳文件只能使用Post(當然還有一個原因,將在後面的提到)。

5、Get限制Form表單的數據集的值必須為ASCII字符;而Post支持整個ISO10646字符集。默認是用ISO-8859-1編碼

6、Get是Form的默認方法。

form有2種方法把數據提交給服務器,get和post,分別說:

Get

1.客戶端(瀏覽器)編碼

  對於get方法來說,都是把數據串聯在請求的url後面作為參數,如:http://localhost:8080/servlet?msg=abc。如果url中出現中文或其它特殊字符的話,如:http://localhost:8080 /servlet?msg=杭州,瀏覽器會對url進行URL encode,然後發送給服務器。URL encode的過程就是把部分url做為字符,按照某種編碼方式(如:utf-8,gbk等)編碼成二進制的字節碼,然後每個字節用一個包含3個字符的字符串 "%xy" 表示,其中xy為該字節的兩位十六進制表示形式,具體介紹可以看下Java.NET.URLEncoder類,我們能看到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.服務器端解碼

  第一步是先把數據用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顯然不行,在程序裏我們可以直接這樣:

new String(request.getParameter("name").getBytes("iso-8859-1"),"客戶端指定的URL encode編碼方式")   

還原回字節碼,然後用正確的方式解碼數據,網上的文章通常是在tomcat裏面做個配置Xml代碼 :

<Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" URIEncoding="GBK"/>   

這樣是讓tomcat在獲取數據後用指定的方式URL decoder

post

1.客戶端(瀏覽器)編碼

在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默認缺省設置,也沒做過濾器等編碼設置,那麽他也是用iso-8859-1解碼的,但是request.setCharacterEncoding("字符集")可以派上用場。 我發現上面說的tomcat所做的事情前提都是在請求頭裏沒有指定編碼方式,如果請求頭裏指定了編碼方式將按照指定的方式編碼。

在form所在的html文件裏如果有段<meta http-equiv="Content-Type" content="text/html; charset=字符集(GBK,utf-8等)"/> 強烈建議使用post提交。

參考文章:http://www.cnblogs.com/yencain/articles/1321386.html

註:以上文章部分摘抄自網絡,忘記註明出處,多望海涵,若有侵權請告知,加以改之!

GET&&POST請求編碼過程