2011年6月23日 星期四

強迫網頁預設編碼語系

強迫網頁預設編碼語系

瀏覽器對於網頁的語系判斷,網路上一堆文章在討論,不過我覺得不太正確,似是而非,所以我寫了這篇文章。

首先,大家都知道網頁的HEADER這行可以決定編碼方式,這個稱之為 META

< meta http-equiv="Content-Type" content="text/html; charset=utf-8">

大部分的瀏覽器如果編碼設成「自動偵測」時都能正確的分析,並以 utf-8 輸出。但世界並不會這麼平順完美,明明我這樣設定時,他就是用 big5 丟出來,或是我明明設定 META 為 big5,但是他丟出來卻是 utf-8,是不是我的瀏覽器不好,所以換了瀏覽器,也許仍不正常(或者是正常後開始罵不正常的瀏覽器爛)。



為何會如此,先來研究一下,在 APACHE 的 httpd.conf 及 php.ini 中都有指定編碼語系的方式,例如:

[httpd.conf]
AddDefaultCharset Big5

[php.ini]
default_charset = "iso-8859-1"

這個萬不得已是不應該去指定的,因為一旦指定,也許能解決一時的問題,但是未來接手管理的人,會毫無頭緒,不知道為什麼編碼怎麼設都不正確,找不出原因。此外,如果在共用的空間中,更沒有辦法去修改 httpd.conf 或是 php.ini 的 charset,常會一個頭兩個大。

接下來我們來研究,為什麼明明 META 就已經正確了,瀏覽器好像視而不見?

先來看看,如果在 httpd.conf 中或是php.ini 已經預設了編碼,瀏覽器取得網頁有什麼不同。這裡我們就要回到 http 這個協定一開始的定義點來看
Hypertext Transfer Protocol -- HTTP/1.1 rfc 2612

瀏覽器在取得網頁內容之前,無論有無讀取過,都會進行一個 HEAD method 以檢查網頁是否有更新,以決定是否要 refresh。所以我們來看一下有定義 charset 和未定義 charset 時取回的 head 有何不同,特別注意,這個 HEAD 不是網頁裡的 < head>標籤中的東西,別搞錯了。

我們來用最原始的定義進行 http 通訊。

[測試參數]

1. 網站 hanbz.example.com (偽) META utf-8 編碼,系統未設定任何預設編碼方式
2. 網站 hanbz.example.com (偽) META utf-8 編碼,系統預設 big5 編碼方式如下(設定在網站 / 目錄的 .htaccess):

AddDefaultCharset Big5

IndexOptions Charset=Big5

[測試]

以下直接用 HEAD 方法取得的內容:
測試 1. hanbz.example.com

# telnet hanbz.example.com 80
Trying 114.33.4.124...
Connected to example.com.
Escape character is '^]'.
HEAD / HTTP/1.1
Host:hanbz.example.com
Connection: close

HTTP/1.1 200 OK
Date: Sat, 24 Apr 2010 06:43:37 GMT
Server: Apache/2.2.9 (ubuntu) mod_ssl/2.2.9 OpenSSL/0.9.8e DAV/2 PHP/5.2.6 with Suhosin-Patch
X-Powered-By: PHP/5.2.6
Set-Cookie: PHPSESSID=m1da8jd9d5rsca810as44qoah2; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Connection: close
Content-Type: text/html

Connection closed by foreign host.

測試 2 . hanbz.example.com

# telnet hanbz.example.com 80
Trying 114.33.4.124...
Connected to example.com.
Escape character is '^]'.
HEAD / HTTP/1.1
Host:hanbz.example.com
Connection: close

HTTP/1.1 200 OK
Date: Sat, 24 Apr 2010 06:44:14 GMT
Server: Apache/2.2.9 (ubuntu) mod_ssl/2.2.9 OpenSSL/0.9.8e DAV/2 PHP/5.2.6 with Suhosin-Patch
X-Powered-By: PHP/5.2.6
Set-Cookie: PHPSESSID=v8hrfte7qvlhs8vmfeu4fgcch3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Connection: close
Content-Type: text/html; charset=Big5 <== 注意看,多出這一行

Connection closed by foreign host.

由此可知,瀏覽器在 HEAD method 完畢後,就自動會切換成 Big5 的編碼,這時就算你在 < META > 中怎麼設定,瀏覽器全都視而不見啦,這和什麼 BOM 一點關係也沒有。

以上文章轉載自:http://note.tcc.edu.tw/477.html

確實是我之前沒有注意到的地方,以往都只有使用meta去做設定,非常值得參考。

沒有留言:

張貼留言

Google Analytics初學者入門簡介