剖析網頁字元集的設定順序

來源:互聯網
上載者:User
字元集

作者:360weboy
新浪微博:http://weibo.com/360weboy
博文連結: http://www.360weboy.com/php/fundament/charset.html

上個星期在為一個電子商務網站進行資料轉移到新系統中的時候,發現一些產品描述字元老是輸出亂碼,確定是字元集的問題以後,對字元集再次進行了一次調研,確定了影響頁面字元集的方式主要下面幾種方式:
1. 檔案的編碼方式
2. Apache2的預設字元集設定
3. PHP.ini中的預設字元集的設定
4. PHP指令碼中手動輸出header(‘Content-type:text/html;charset=xxx’);
5. html頁面中加入
我對以上五種方式都進行了一一測試,並且確定了5種方式對於瀏覽器字元集選擇的優先順序。首先我建立了一個以utf8編碼的test.php檔案,內容如下:



我使用chrome訪問test.php, 因為我的chrome瀏覽器的預設字元集不是utf8,應該是gb2312或者gbk,所以我在瀏覽器中看到了如下亂碼:



header與meta的優先順序比較

接下來,先來測試以上的4,5兩種方式。我向html頁面中分別加入了,內容顯示正常。





去掉header中的meta標籤,加入header(‘Content-type:text/html;charset=utf8′);內容顯示正常。那麼,meta標籤和header的方式,那個優先順序高呢,我在頁面裡同時設定了這兩項,header設定為gb2312, meta設定為utf8:



結果內容顯示不正常,說明header的優先順序高。瀏覽器先採用http頭部中的字元集設定,然後是html頁面中meta標籤設定的字元集。



php.ini中設定預設字元集以後的影響

接下來,我們來看下在php.ini中設定預設字元集以後的情形。為了測試下優先順序,我們先將頁面中的header以及meta設定的字元集都改為gb2312,那麼這樣內容肯定顯示為亂碼。然後,我們開啟php.ini檔案,找到如下設定,去掉前面的引號,設定字元集為utf8:



設定好以後,記得要重啟下apache2伺服器,結果顯示如下:



我們看到,在php.ini設定預設字元集為utf8以後,它被加入到了回應標頭Content-type末尾,從而覆蓋了在php指令碼中通過header函數輸出的gb2312的字元集,瀏覽器根據該頭部中的資訊,認為內容是utf8的字元集,最後內容現實正常。由此可見,php.ini中字元集設定的優先順序高於header函數以及meta標籤。

apache2中設定預設字元集

最後,我們來設定下apache2中的預設字元集來測試下。這次將header,meta,php.ini中的字元集都設定為gb2312,然後在apache2設定預設字元集為utf8:



重啟apache2伺服器,內容顯示如下:





由此可見,apache2中的字元集的設定沒有影響到http響應中的Content-Type頭部,所以瀏覽器認為應該用gb2312來解碼,導致出現亂碼。那麼,如果去掉php.ini中的字元集的設定以後內,頁面是否會顯示正常。經過測試,顯示如下:



看來,apache2中的字元集的優先順序同樣小於header函數的字元集設定。我們繼續去掉header的設定看下:

以上證明,apache2中的字元集設定的優先順序高於meta標籤的字元集設定。charset=utf8加入到了http頭部中。
綜合上述實驗,得出字元集設定優先權順序: php.ini預設字元集設定 > header函數字元集設定 > apache2預設字元集設定 > meta標籤字元集設定


回複討論(解決方案)

這個結果不太認同

測試有局限性
1.只使用了單一瀏覽器測試
2.只使用了一種語系測試
3.只使用了單一檔案編碼測試

最大的問題是所有測試都是正向測試,就是符合預期就認為該項是正確的,這是邏輯大忌

為什麼實驗過程沒有問題,但得出的結論是錯誤的呢?
經測試:
default_charset 的優先順序小於 header 函數字元集設定

優先順序的順序根據我和朋友的測試是對的,請自己核對。

snmr_com

請指教,你知道測試問題所在,那麼能不能說下,這個過程應該怎麼測試才算標準。。多謝!

http://www.w3help.org/zh-cn/causes/HR9001
可以參考這邊文章,但這文章也比較舊了

你用的是歸納法推導,完全歸納法的基礎就是滿足所有的可能性得出一致(唯一)結論
並且,因為你的這個命題各種可能性並非符合“良序”特性,不能用數學歸納法那樣的兩步求證
所以,你要做測試就要遍曆所有的可能性,如果沒有遍曆所有可能性,那麼結論就只能增加限定條件
例如
只涉及一種瀏覽器,結論就只能縮小到該瀏覽器
原文檔只使用了一種編碼,那結論也只能適用於這種編碼

基本上增加了兩三個限定條件,結論就沒有太大的實用意義,因為適用範圍變得很小了
所以還是要做更多的測試以支援你的結論才行
你命題涉及的條件有:瀏覽器、各優先順序的編碼指定、語系(特別是較難自動識別的不同語系,如同是雙位元組中日韓編碼)、文檔編碼,做一個排列組合,可能性就相當多了……如果能全部測試一遍,還是相當佩服你的,呵呵

專業的理論指導,兄弟佩服。。。有時間再完整的走一遍。。多謝回複

優先順序的順序根據我和朋友的測試是對的,請自己核對。 php.ini



運行介面


你測試的結果並不代表我測試的結果
何況 header 就該能改變相關預設值,否則還要他幹什嗎?

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.