如果你在網上搜索
“
apache
配置
”
,搜到的頁面大多都會建議你在
httpd.conf
中加上這麼一句:
AddDefaultCharset GB2312
。對於新手而且是隻用
GB2312
編碼的開發人來說,這麼做是
ok
的。
但是如果要想使用
UTF-8
字符集的話,比如
在
test.php
文件中需要有
meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
這段代碼。這時你再打
開瀏覽器訪問
test.php
頁面的話,你看到的是正確的頁面。但是如果實際上瀏覽器還是以
GB2312
編
碼解釋從服務器返回的
response
,爲什麼呢?原因是瀏覽器是根據
http
應答消息頭部中的
Content-type: text/html; charset=GB2312
來決定使用何種編碼解釋應答,也就是說
apache
服務
器仍然用
GB2312
編碼傳遞數據。
所以說如果
apache
的默認字符集被設置成了
GB2312
,
即使在頁面中聲明使用
UTF-8
編碼,
apache
服務
器還是會按照
GB2312
編碼來傳送
http response
。
沒關係,我們把
AddDefaultCharset GB2312
改成
AddDefaultCharset UTF-8
,看看什麼結果?如果
你看到亂碼恭喜你,你還知道是亂碼問題;如果你看到是空白頁面,那麼你就慘了,你可能會以爲
這是其他什麼原因造成的,而不會從編碼的角度去考慮怎麼解決問題。這是爲什麼?
原因在於
php
文件本身是用系統字符集來編碼的,中文的
windows
XP
都是用
GB2312
,每一個文件頭部
都有字段指示該文件是用何種方式編碼的。當
apache
接到瀏覽器的請求後,會讓
php
去解釋所請求的
頁面,比如
test.php
。
php
會識別出
test.php
的編碼方式是
GB2312
後
(
就像我們用
javac
編譯
java
源
文件時,編譯器默認用系統編碼讀源文件裏的內容。如果源文件不是用系統編碼來保存的,可以用
命令
javac -encoding
指定具體的編碼
)
,把數據以
GB2312
的編碼格式傳遞給
apache
,而
apache
服務
器不會改變從
php
傳來的數據,只是在應答消息頭部中把字符集設置成
UTF-8
:
Content-type:
text/html; charset=UTF-8.
也就是說你傳遞的是
GB2312
編碼的數據,而瀏覽器卻以
UTF-8
編碼來解
釋應答消息。
由於
UTF-8
爲
3
個字節表示一個漢子,而普通的
GB2312
或
BIG5
是兩個。頁面輸出時,由於上述原因,
出現半個漢字的情況,這時該半個漢字會和的
>
結合成一個亂碼字,導致
IE
無法讀完的話,會發現
實際上整個葉面全部已經輸出了。如果使用的是
Mozilla
、
Mozilla Firefox
、
Sarafi
的瀏覽器這不
會造成這個問題,而是一堆亂碼。這是由於
Firefox
瀏覽器和
IE
解析網頁編碼的策略不同產生的。
OK,
我們把
test.php
以
UTF-8
保存,再用瀏覽器訪問時,就沒有問題了。可這樣做,會使得
apache
目
錄下的所有
web
應用只能用同一種編碼。如何搞定?
解決辦法:
首先,可以使用
AddDefaultCharset
off
來關閉默認文件編碼,這樣
apache
服務器就不會在
http
應答
消息頭部設置
charset
,只是設置
Content-type: text/html.
而瀏覽器就會依靠
html
文件中設置的
harset
來決定編碼。其次,腳本
php.ini
文件中的
default_charset =
“
UTF-8
″作用同
httpd.conf
文
件,把該行註釋掉,使
php
自動識別文件的編碼方式。
這樣不論你用什麼編碼方式,只要
test.php
中的
meta http-equiv=
”
Content-Type
”
content=
”
text/html; charset=UTF-8
″
與你
test.php
文件編碼
方式相同,就不會產生亂碼問題。
用戶提交數據的編碼
瀏覽器提交的字符編碼由客戶端的
characher encoding
決定。例如,當前瀏覽器的編碼是
Gb2312
,
用戶提交數據後,
無論
apache
設置的編碼方式是
GB2312
還是
UTF-8
,
這時在服務器端接收到的仍是以
Gb2312
編碼的數據。如果要在返回頁面上顯示用戶剛纔提交的數據,而該頁面是用
UTF-8
編碼,或者
要在數據庫中存儲的用戶提交的數據,而數據庫是
UTF-8
編碼的,那就要做字符轉換了。