在web開發中遇到最頭痛的問題莫過於亂碼的問題,亂碼的問題看似簡單,其實是很複雜的,涉及的知識面太廣,作業系統的編碼、檔案編碼、伺服器返回的資料所使用的編碼、伺服器告訴瀏覽器返回資料所使用的編碼、瀏覽器展示頁面時所使用的編碼等等,要真正明白各種亂碼的原因,你甚至還要理解各種編碼的編碼原理,像utf-8、utf-16、gbk等。下面由乙個簡單的程式來引出主題的**:
@controller
public class testcontroller}
上面是spring mvc乙個簡單的controller向客戶端輸出一段中文字串,下面是瀏覽器(firefox4.0.1)的輸出
從伺服器返回的資料長度可知道,資料的確是按照utf-8編碼的,但響應頭並沒有編碼資訊,即瀏覽器並不知道伺服器返回的資料編碼方式,由accept-charset知,瀏覽器展示頁面用的utf-8編碼,那麼瀏覽器怎麼講伺服器的資料展示出來呢?
瀏覽器要展示必須將伺服器端的資料轉換為utf-8編碼,但瀏覽器並不知道伺服器資料的編碼方式如何轉換呢?當瀏覽器不知道伺服器返回資料的編碼方式時,就把它的編碼方式當做和作業系統的字符集編碼一樣。因為我使用的是中文作業系統,所以瀏覽器展示頁面時,就將伺服器返回的資料以gb2312的方式轉換為utf-8的編碼。但上圖中伺服器返回的資料實際是utf-8編碼的,有9個位元組,被當做gb2312來處理當然會有問題。
上面的根本問題就在於瀏覽器把伺服器utf-8編碼的資料當做gb2312編碼來處理,那如何讓瀏覽器知道伺服器返回資料的編碼方式呢?很簡單,在響應頭中設定編碼方式就行了,像下面這樣:
res.setcontenttype("text/plain;charset=utf-16")
res.getwriter.write("世界,我來了")
或res.setcharacterencoding("utf-16")
res.setcontenttype("text/plain")
res.getwriter.write("世界,我來了")
瀏覽器的輸出:
你可能會覺得奇怪,為什麼伺服器的資料編碼是utf-16(content-type中指定的,資料長度也是14),瀏覽器展示頁面用的utf-8的編碼(accept-charset中指定的),而沒有出現亂碼?這是因為瀏覽器知道伺服器返回資料的編碼方式是utf-16後,它會就資料從utf-16的方式轉換為utf-8編碼,資料就能正確展示出來。所以charset中不管你指定什麼編碼(前提是這種編碼支援中文,像iso8859就不支援中文。如果指定為iso8859編碼,就會有資料丟失,就不能轉換accept-charset指定的編碼),瀏覽器都能正確展示。
到這裡,你應該似乎明白了資料在伺服器和瀏覽器之間的編碼轉換過程。那我們再看下面的例子:
res.setcharacterencoding("utf-16")
res.getwriter.write("世界,我來了")
瀏覽器輸出:
上面這幅圖除了響應頭的資料長度(由資料長度可知伺服器端資料的編碼方式確實是utf-16),響應和請求頭其他的資訊和第一幅圖一樣,那瀏覽器為什麼能正確顯示資料呢?這是因為由於沒有指定伺服器端返回資料的編碼方式(即conent-type中沒有指定charset),瀏覽器就把伺服器返回的資料當做gb2312編碼來轉換為utf-8編碼來展示出來,而原來是utf-16編碼的資料當做gb2312來處理時沒有問題的,具體原因大家可以去看gb2312和utf-18的編碼原理,所以瀏覽器能正確顯示資料。
這案例中有以下幾點要注意:
1、若只呼叫setcharacterencoding(),則只是高告訴伺服器返回的資料的編碼方式,並沒有告訴瀏覽器資料的編碼方式(即不會產生content-type頭欄位)。
2、只有在呼叫setcontenttype()時指定具體的mime-type才會產生conent-type頭欄位,若沒有呼叫setcharacterencoding(),也沒有指定charset,則會使用charset則會被設定為iso8859-1;呼叫了setcharacterencoding(),則使用該方法指定的字符集
3、setcontenttype()中設定的charset會覆蓋setcharacterencoding()方法。
部落格新位址
瀏覽器與伺服器
瀏覽器是安裝在電腦裡面的乙個軟體,能夠將頁面內容渲染出來呈現給使用者檢視,並讓使用者與網頁互動的一種軟體。常見主流瀏覽器 internet explorer,chrome,firefox,safari,opera 瀏覽器核心 瀏覽器所採用的渲染引擎。渲染引擎決定了瀏覽器如何顯示網頁的內容,以及網頁格...
WEB 伺服器 與 瀏覽器
http協議通訊,是連線瀏覽器和伺服器的橋梁。兩者之間的資訊流,使它們真正的活力。這中間,瀏覽器連著使用者 伺服器連著資料庫 等其他的服務。伺服器能提供給瀏覽器,什麼樣的資訊呢?這些資訊,遵循著http通訊的格式。也許,瀏覽器只是 的乙個視窗,通過使用瀏覽器我們訪問 而真正的 技術,卻被掩蓋掉了。技...
瀏覽器訪問伺服器的流程
1 瀏覽器輸上網域名稱,例如www.baidu.com 2 瀏覽器會先訪問dns伺服器,把網域名稱解析成ip位址,在返回給瀏覽器 2 dns的解析原理 原理步驟 1 系統首先會查詢本地的dns快取和hosts檔案資訊,確認其中是否有與,網域名稱www.baidu.com所對應的ip位址。如果有,就直...