??? 今天看了子華的博客中關于昨晚我們討論編碼方面的問題,發現其中有一個關鍵點沒有談到。
??? 情況是這樣的:我們現在使用的一個名為Notepad++的編輯器,它大體上和UltraEdit類似,是我從sourceforge上下載下載使用的。它有個格式的功能,簡單而言就是設置使用ascii編碼編輯文檔還是使用utf-8編碼,其實這里主要是對應非英文方面的字符才發生差異。
??? 如前那篇隨筆所述utf-8只是用于在數據傳輸時將字符串分割成字節傳輸出去,它對于unicode編碼有著嚴格的一一對應關系,而對于gb2312、gbk、gb18030之類的中文編碼是沒有對應關系的。gb2312、gbk、gb18030是在ascii編碼之上進行的中文編碼開發,所以它們是與ascii相兼容的,可以這么理解在我們的文本編輯器中ascii方式編輯的文本是以ascii碼保存,而以utf-8方式編輯的文本是以unicode編碼保存。
??? 現在,編碼的差異就在這里發生了,unicode中的英文部分編碼是與ascii相兼容的,具體而言是iso8859-1兼容,所以我們無論用什么編碼保存方式保存jsp文件,在網頁上顯示的都是正確的英文字符。但是對于中文這個保存的格式卻非常重要。在了解了jsp頁面的顯示過程我們就會明白其中的原因。
??? 現在回頭來看看jsp文件是經過了哪些步驟才在網頁上顯示出來的。
??? 1、首先我們用編輯器編輯jsp頁面代碼保存;
??? 2、web服務器對其進行編譯,將jsp頁面編譯成為一個java的class文件;
??? 3、web服務器將其class文件用傳輸格式在網絡上傳輸;
??? 4、客戶端瀏覽器解析代碼生成頁面。
??? 過程大致如上,能夠影響編碼方面的基本上在1、2、4方面,所以對其進行詳細講解。
??? 我們的編輯器是有一種默認的編碼保存方式的。這會到后面java編譯器是否將其中的中文進行轉換的問題。大家都知道java是以十六位的unicode編碼編譯、存儲java文件的。因為同一個漢字在unicode編碼和gb2312編碼中的位置是不一樣的,(具體而言就是這兩種編碼沒有兼容性,也不能通過公式換算出來,只能通過字符對應表進行轉換)
??? 上面指出的保存格式的重要性就在這里體現出來了,這也是很多人容易遺漏之處,當我們用默認格式位gbk的編輯器編輯jsp頁面,而在其頭部聲明charset=utf-8,那么返回的頁面會出現亂碼,而charset=gb2312則正常顯示。本人分析原因在于,在charset=utf-8的聲明有誤時,java編譯器會錯誤的認為現在保存的文件就是以unicode編碼格式保存的文件,所以在編譯中就不對其中的中文字符進行gb2312--unicode的轉化,而直接將其gb2312指向的編碼地址保存為unicode的編碼地址。反之,當編輯器的默認編輯保存格式為utf-8時,在jsp中聲明為gb2312,就會讓編譯器畫蛇添足的多進行一次中文編碼轉換,從而亂碼出現。
??? 綜上所述,編輯器的默認編碼方式是在解決中文亂碼方面是很重要的一個因素,當然我們可以用pageEncoding參數來說明文本編碼形式。弄清中文顯示后面的具體調用過程是徹底解決該類問題的終極之道!
??? 情況是這樣的:我們現在使用的一個名為Notepad++的編輯器,它大體上和UltraEdit類似,是我從sourceforge上下載下載使用的。它有個格式的功能,簡單而言就是設置使用ascii編碼編輯文檔還是使用utf-8編碼,其實這里主要是對應非英文方面的字符才發生差異。
??? 如前那篇隨筆所述utf-8只是用于在數據傳輸時將字符串分割成字節傳輸出去,它對于unicode編碼有著嚴格的一一對應關系,而對于gb2312、gbk、gb18030之類的中文編碼是沒有對應關系的。gb2312、gbk、gb18030是在ascii編碼之上進行的中文編碼開發,所以它們是與ascii相兼容的,可以這么理解在我們的文本編輯器中ascii方式編輯的文本是以ascii碼保存,而以utf-8方式編輯的文本是以unicode編碼保存。
??? 現在,編碼的差異就在這里發生了,unicode中的英文部分編碼是與ascii相兼容的,具體而言是iso8859-1兼容,所以我們無論用什么編碼保存方式保存jsp文件,在網頁上顯示的都是正確的英文字符。但是對于中文這個保存的格式卻非常重要。在了解了jsp頁面的顯示過程我們就會明白其中的原因。
??? 現在回頭來看看jsp文件是經過了哪些步驟才在網頁上顯示出來的。
??? 1、首先我們用編輯器編輯jsp頁面代碼保存;
??? 2、web服務器對其進行編譯,將jsp頁面編譯成為一個java的class文件;
??? 3、web服務器將其class文件用傳輸格式在網絡上傳輸;
??? 4、客戶端瀏覽器解析代碼生成頁面。
??? 過程大致如上,能夠影響編碼方面的基本上在1、2、4方面,所以對其進行詳細講解。
??? 我們的編輯器是有一種默認的編碼保存方式的。這會到后面java編譯器是否將其中的中文進行轉換的問題。大家都知道java是以十六位的unicode編碼編譯、存儲java文件的。因為同一個漢字在unicode編碼和gb2312編碼中的位置是不一樣的,(具體而言就是這兩種編碼沒有兼容性,也不能通過公式換算出來,只能通過字符對應表進行轉換)
??? 上面指出的保存格式的重要性就在這里體現出來了,這也是很多人容易遺漏之處,當我們用默認格式位gbk的編輯器編輯jsp頁面,而在其頭部聲明charset=utf-8,那么返回的頁面會出現亂碼,而charset=gb2312則正常顯示。本人分析原因在于,在charset=utf-8的聲明有誤時,java編譯器會錯誤的認為現在保存的文件就是以unicode編碼格式保存的文件,所以在編譯中就不對其中的中文字符進行gb2312--unicode的轉化,而直接將其gb2312指向的編碼地址保存為unicode的編碼地址。反之,當編輯器的默認編輯保存格式為utf-8時,在jsp中聲明為gb2312,就會讓編譯器畫蛇添足的多進行一次中文編碼轉換,從而亂碼出現。
??? 綜上所述,編輯器的默認編碼方式是在解決中文亂碼方面是很重要的一個因素,當然我們可以用pageEncoding參數來說明文本編碼形式。弄清中文顯示后面的具體調用過程是徹底解決該類問題的終極之道!
本文依據《創作共用約定》之“署名-禁止派生-非商業用途”方式發布,即你可以免費拷貝、分發、呈現和表演當前作品,但是必須基于以下條款:
署名:你必須明確標明作者的名字。
非商業用途:你不可將當前作品用于商業目的。
禁止派生:你不可更改、轉變或者基于此作品重新構造為新作品。
對于任何二次使用或分發,你必須讓其他人明確當前作品的授權條款。
在得到作者的明確允許下,這里的某些條款可以放棄。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="GBK"%>
要不然你就得用編輯器另存為的時候(例如記事本就有這個功能, 但是貌似有問題)轉換編碼為 UTF-8.
服務器看到 contentType="text/html; charset=UTF-8" 的頁面聲明的時候, 就認為下面的內容都是 UTF-8, 如果這時候不加上 pageEncoding, 出來的內容自然就是亂碼.
因此要么都用 GBK, 要么都用 UTF-8. 可以在 Eclipse 里進行設置讓所有的源文件的默認字符集都是 UTF-8. 如果要做開源項目, 強烈建議的是不要用 GBK 格式的編碼, 用 UTF-8 是上上策. 還有就是鼓勵英文注釋, 網頁內容國際化, 呵呵.
2、web服務器對其進行編譯,將jsp頁面編譯成為一個java的class文件;
3、web服務器將其class文件用傳輸格式在網絡上傳輸;
4、客戶端瀏覽器解析代碼生成頁面。
非applet的情況下,服務器怎么可能把class傳輸到網絡上去,瀏覽器又怎么可能解析class?服務器傳輸的是html,class生成html的過程早在服務器端就已經完成。
亂碼的直接原因就在于服務器在頭里告訴瀏覽器的編碼 charset=UTF-8 和事實上生成html的編碼是不一致的
應該是:
1. 我們用代碼編輯器編輯了一個頁面(encoding=GBK)
2. Web 服務器調用編譯器將其編譯為 servlet(編譯器也會有個 encoding 選項, 一般都是跟著系統的 encoding 走, 頁面有 charset 的話就跟頁面的 charset 或者 pageEncoding 一致, 所以有時候不指定JSP編譯默認編碼, 不同的服務器出來的結果就不一樣), (encoding=GBK);
3. 生成 HTML, 這沒啥, 直接 write string;
4. 瀏覽器根據 head 里的 contentType (UTF-8)來判斷編碼, 或者根據頁面里的 meta 來判斷編碼
<meta http-equiv="content-type" content="text/html; charset=UTF-8">, 什么都沒的時候就當成西歐字符集, 具體哪個優先? 印象中是頁面里的 meta 優先, 這時候客戶需要手工選一個編碼才能看到正確的網頁.
所以只有這些條件都一致的時候, 才不會亂碼, 否則都會亂碼. 一般推薦全用 UTF-8(英文服務器環境) 或者 GBK(中文服務器).
gb18030也和unicode有著嚴格的一一對應關系,gb2312、gbk和unicode的子集有著嚴格的一一對應關系
UTF-8和gb18030都是所謂的外碼標準
“gb2312、gbk、gb18030是在ascii編碼之上進行的中文編碼開發,所以它們是與ascii相兼容的”是錯誤的,只能說UTF-8以及國標編碼的單字節編碼區和ascii的0~7F區的編碼是一致的。
Notepad++和UltraEdit的ascii其實并不是ascii,而是指Windows平臺的本地多字節字符集,一般咱們用的中文Windows上就是gbk
這個是對的嗎?本人好像沒有看到這樣的資料,gb18030只是一部分與unicode對應,不會是全部一一對應吧