web開發中的字符編碼問題

三種常用的字符集編碼:

UTF-8:Unicode TransformationFormat-8bit,允許含BOM,但通常不含BOM。是用以解決國際上字符的一種多字節編碼,它對英文使用8位(即一個字節),中文使用24位(三個字節)來編碼。UTF-8包含全世界所有國家需要用到的字符,是國際編碼,通用性很強。UTF-8編碼的文本可以在各國支持UTF8字符集的瀏覽器上顯示。如,如果頁面的編碼格式是UTF8,則在外國人的英文IE上也能顯示中文,他們無需下載IE的中文語言支持包。 

GBK是國家標準GB2312基礎上擴容後兼容GB2312的標準。GBK的文字編碼是用雙字節來表示的,即不論中、英文字符均使用雙字節來表示,爲了區分中文,將其最高位都設定成1。GBK包含全部中文字符,是國家編碼,通用性比UTF8差,不過UTF8佔用的存儲空間比GBK大。 

GBK、GB2312等與UTF8之間都必須通過Unicode編碼才能相互轉換
 
區分四種編碼設置:
(1)<%@ page language="java" import="java.util.*   pageEncoding="GBK" "%>
(2)<%@ page contentType="text/html;charset=GBK"%>
(3)request.setCharacterEncoding("GBK");
(4)response.setCharacterEncoding("GBK");
 
(1)(2)僅在JSP頁中使用,(3)(4)可在JSP頁面或服務端的Servlet中使用。
 
如果服務端的某個JSP頁面被請求,應用容器會先把被請求的JSP轉換爲一個java類(也就是servlet)再編譯這個類生成XX.class文件,然後執行這個setvlet最後把生成的頁面返回給客戶端
 
(1)<%@ page language="java" import="java.util.*   pageEncoding="GBK" "%>
告訴jsp編譯器在將jsp編譯成servlet時使用的編碼,通常在jsp中定義的字符串出現亂碼時多數是由於這個參數設置錯誤引起的。
另外,如果在JSP中不指定contentType參數值,也不使用(4),則(1)還可以指定對服務器響應進行重新編碼時用的編碼格式。
(2)<%@ page contentType="text/html;charset=GBK"%>
在不使用response.setCharacterEncoding("GBK");時,她指定對服務器響應進行重新編碼時用的編碼格式。
(3)request.setCharacterEncoding("GBK");
將請求數據進行重新編碼,參數指定編碼格式。
(4)response.setCharacterEncoding("GBK");
對響應數據進行重新編碼,參數指定編碼格式。
**服務器把數據發到客戶端前,都要對數據進行重新編碼。
 
另外, 瀏覽器是怎樣對接受和發送的數據進行編碼、解碼的呢?
(4)response.setCharacterEncoding("GBK");
的設置,不僅可以對響應數據進行重新編碼爲參數的格式,還告訴瀏覽器, 以參數的編碼格式進行解碼。
瀏覽器在發送數據時,也是按照response.setCharacterEncoding("GBK");的參數進行編碼的,以百度和谷歌爲例,在搜索框中輸入“漢字”
百度會將其編碼爲"%BA%BA%D7%D6"
谷歌會將其編碼爲"%E6%B1%89%E5%AD%97"
這是由於response.setCharacterEncoding("XXX"),百度的參數是GBK, 谷歌的是UTF-8。
 
瀏覽器在接收服務器數據和發送數據到服務器時所使用的編碼是相同的,默認情況下均爲JSP頁面的response.setCharacterEncoding參數(或者contentType和 pageEncoding參數)我們稱其爲瀏覽器編碼。當然,在IE中可以修改瀏覽器編碼(在IE的菜單中選擇"查看(V)"à"編碼(D)"中修改),但通常情況下,修改該參數會使原本正確的頁面中出現亂碼。一個有趣的例子是,在IE中瀏覽GOOGLE的主頁時,將瀏覽器編碼修改爲"簡體中文(GB2312)",此時,頁面上的中文會變成亂碼,不理它,在文本框中輸入"漢字",提交,GOOGLE會將其編碼爲"%BA%BA%D7%D6",可見,瀏覽器在對中文進行URL編碼時,使用的就是瀏覽器編碼。
那麼服務器是怎樣對接受和發送的數據進行編碼、解碼的呢?
對於發送數據,服務器按照response.setCharacterEncoding—contentType—pageEncoding的優先順序,對要發送的數據進行編碼。  
對於接收數據,要分三種情況。一種是瀏覽器直接用URL提交的數據,另外兩種是用表單的GET和POST方式提交的數據。
因爲各種WEB服務器對這三種方式的處理也不相同,所以我們以Tomcat爲例。   無論使用那種方式提交,如果參數中包含中文,瀏覽器都會使用當前瀏覽器編碼格式對其進行URL編碼。
 
一、對於表單中POST方式提交的數據,只要在接收數據的jsp/servlet中request.setCharacterEncoding(“參數”),即對客戶端請求參數進行重新編碼的編碼格式設置成瀏覽器編碼,就可以保證得到的參數編碼正確。
那如何得到瀏覽器編碼呢?上面提過了,在默認請情況下,瀏覽器編碼就是你在響應該請求的JSP頁面中response.setCharacterEncoding設置的值。所以對於POST表單提交的數據,在獲得數據的JSP頁面中request.setCharacterEncoding要和生成提交該表單的JSP頁面的 response.setCharacterEncoding設置成相同的值。
 
二、對於URL或GET方式提交的數據,因服務器的不同,處理方式不同,例如tomcat對這兩種方式的提交默認ISO-8895-1進行解碼(request.setCharacterEncoding是不行的。)
要解決該問題,應該在Tomcat的配置文件的Connector標籤中設置useBodyEncodingForURI或者 URIEncoding屬性,其中useBodyEncodingForURI參數表示是否用request.setCharacterEncoding 參數對URL提交的數據和表單中GET方式提交的數據進行重新編碼,在默認情況下,該參數爲false
 URIEncoding參數指定對所有GET方式請求(包括URL提交的數據和表單中GET方式提交的數據)進行統一解碼。 URIEncoding和useBodyEncodingForURI區別是,URIEncoding是對所有GET方式的請求的數據進行統一解碼,而useBodyEncodingForURI則是根據響應該請求的頁面的request.setCharacterEncoding參數對數據進行解碼
 
下面總結下,以Tomcat5.0爲WEB服務器時,如何防止中文亂碼。   1.對於同一個應用,最好統一編碼,推薦爲UTF-8,當然GBK也可以。   2.正確設置JSP的pageEncoding參數  3.在所有的JSP/Servlet中設置contentType="text/html;charset=UTF-8"或response.setCharacterEncoding("UTF-8"),從而間接實現對瀏覽器編碼的設置。   4.對於請求,可以使用過濾器或者在每個JSP/Servlet中設置request.setCharacterEncoding("UTF-8")。同時,要修改Tomcat的默認配置,推薦將useBodyEncodingForURI參數設置爲true,也可以將URIEncoding參數設置爲 UTF-8(有可能影響其他應用,所以不推薦)。
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章