關(guān)于亂碼的筆記

在瀏覽器上查看網(wǎng)頁(yè),偶爾會(huì)看到一些網(wǎng)站出現(xiàn)亂碼的情況。關(guān)于瀏覽器展示亂碼,這里做個(gè)簡(jiǎn)單的介紹。

認(rèn)識(shí)幾種編碼方式
ASCII
全稱(chēng)美國(guó)標(biāo)準(zhǔn)信息交換代碼(American Standard Code for Information Interchange)的縮寫(xiě), 為美國(guó)英語(yǔ)通信所設(shè)計(jì)。它由128個(gè)字符組成,包括大小寫(xiě)字母、數(shù)字0-9、標(biāo)點(diǎn)符號(hào)、非打印字符(換行符、制表符等4個(gè))以及控制字符(退格、響鈴等)組成,每個(gè)字符占7位(1字節(jié)是8位)。
ISOLatin-1
可以認(rèn)為ASCII是美國(guó)發(fā)明針對(duì)英語(yǔ)設(shè)計(jì)的,但歐洲人在用的時(shí)候出現(xiàn)了問(wèn)題。對(duì)于一些特殊的拉丁字符,比如法文德文里某些字符,ASCII字符集就不包括。于是歐洲人發(fā)明了一種8位字符集是ISO 8859-1Latin 1,也簡(jiǎn)稱(chēng)為ISOLatin-1。它對(duì)ASCII做了個(gè)擴(kuò)充,對(duì)于0-127之間的字符還使用ASCII里的字符不變, 把位于128-255之間的字符表示拉丁字母表中特殊語(yǔ)言字符。
UNICODE
后來(lái)計(jì)算機(jī)不斷發(fā)展擴(kuò)展到亞洲非洲,如何用計(jì)算機(jī)使用的二進(jìn)制表示這些語(yǔ)言又成了問(wèn)題。ISOLatin-1的8位字符集只能表示256個(gè)字符,而僅漢語(yǔ)就有80000以上個(gè)字符。如何把地球上絕大多數(shù)語(yǔ)言用一種編碼方式表示出來(lái)呢? 于是發(fā)明了UNICODE編碼,只用2個(gè)字節(jié)(16位)就可以編碼地球上幾乎所有地區(qū)的文字。但是,UNICODE只是理論上的編碼方式,相當(dāng)于給世界上每個(gè)文字打了個(gè)編號(hào),但這編號(hào)具體如何在計(jì)算機(jī)里面存儲(chǔ),可以有多種實(shí)現(xiàn)方式。比如utf-8和gbk。
前面說(shuō)了UNICODE只是給每個(gè)文字打了個(gè)編號(hào),為啥不把這個(gè)編號(hào)直接轉(zhuǎn)化成二進(jìn)制存儲(chǔ)在計(jì)算機(jī)里面呢? 比如英文字母s
的編號(hào)是115
, 用二進(jìn)制表示是00000000 1110011
, 中文日
的編號(hào)是26085 (16進(jìn)制是65e5) ,二進(jìn)制是11001011 1100101
。老外才沒(méi)那么傻,對(duì)于老外這種日常純粹是用英文字符的人來(lái)說(shuō)明明之前1個(gè)字節(jié)就能存儲(chǔ)一個(gè)字母,現(xiàn)在為了全球大一統(tǒng)非要存儲(chǔ)為2個(gè)字節(jié),相當(dāng)于一個(gè)之前一個(gè)1M的文檔,現(xiàn)在變?yōu)?M。于是老外耍了賴(lài),英文字母s
是115
沒(méi)錯(cuò),但我就用1個(gè)字節(jié)1110011
表示,而你中文日
是26085
號(hào)也沒(méi)錯(cuò),但是你不能在使用2個(gè)表示,而是用2個(gè)甚至6個(gè)字節(jié)表示。(為了英文的特權(quán),犧牲其他語(yǔ)言的存儲(chǔ)空間的便利),這個(gè)編碼方式就是UTF-8。
UTF-8
utf-8(8-bit Unicode Transformation Format)是一種針對(duì)Unicode的可變長(zhǎng)度字符編碼,又稱(chēng)萬(wàn)國(guó)碼。UTF-8用1到6個(gè)字節(jié)編碼UNICODE字符。用在網(wǎng)頁(yè)上可以同一頁(yè)面顯示中文簡(jiǎn)體繁體及其它語(yǔ)言(如英文,日文,韓文)。
那GBK又是如何產(chǎn)生的呢?
GBK
這時(shí)候中國(guó)不干了,為啥你制定了全球大一統(tǒng)的規(guī)則,卻為了自己的便利又破壞規(guī)則,把方便留給自己不便留給別人呢? 明明用2個(gè)字節(jié)就能表示中文一個(gè)漢字,現(xiàn)在UTF-8編碼中文竟然需要2個(gè)甚至4個(gè)字節(jié)來(lái)表示。于是中國(guó)制定一套自己的規(guī)則,于是用2個(gè)字節(jié)來(lái)表示一個(gè)漢字,總共可以覆蓋2萬(wàn)多個(gè)文字。 對(duì)于英文,好吧讓一步,還保留和你UTF-8同樣的方式使用一個(gè)字節(jié)來(lái)表示。
記?。篣NICODE只是給字符一個(gè)代號(hào),而GBK和UTF-8使用不同的規(guī)則來(lái)表示同一個(gè)代號(hào)。
網(wǎng)頁(yè)亂碼如何產(chǎn)生
下面這個(gè)流程是我們寫(xiě)入文件到展示文件的簡(jiǎn)單描述:
我們使用編輯器編寫(xiě) HTML 文件
保存編寫(xiě)的HTML文件
使用瀏覽器打開(kāi)HTML文件
HTML文件在瀏覽器展示

亂碼產(chǎn)生的根源就在與第2步驟和第4步。
在第2步保持文件時(shí)會(huì)把我們寫(xiě)入的文字使用編輯器默認(rèn)的編碼方式進(jìn)行保存。如果大家使用的是Sublime編輯器,默認(rèn)的編碼方式是utf-8。當(dāng)然也可以安裝GBK Encoding support
插件,在保存文件時(shí)可選擇保存為GBK


在第4步瀏覽器打開(kāi)網(wǎng)頁(yè)時(shí),它并不知道你的這個(gè)文件是使用什么編碼方式,于是自作主張使用了默認(rèn)解碼方式。如下圖所示,文件保存為GBK格式,在Chrome打開(kāi)時(shí)默認(rèn)使用 ISO -8859的解碼方式,導(dǎo)致編碼和解碼不匹配,產(chǎn)生亂碼。
0_1452962458223_屏幕快照 2016-01-17 上午12.38.50.png

那如何規(guī)避這個(gè)問(wèn)題呢?即如何通知瀏覽器用什么方式解碼呢?
首頁(yè),在文件保存的時(shí)候你自己要清楚是用哪種編碼方式保存的(sublime默認(rèn)保存方式是utf-8,如果安裝了插件也可另存為gbk,其它IDE可以做設(shè)置保存格式)。如果你的文件是保存為utf-8格式,那么一定要在html 的 <head>
里添加<meta charset="utf-8">
,這句話的意思是告訴瀏覽器在打開(kāi)這個(gè)頁(yè)面的時(shí)候不要去猜了,直接用utf-8去解碼。 同理,如果你的文件保存為gbk格式,一定在文件里添加<meta charset="gbk">

記住,
亂碼產(chǎn)生的根本原因是你保存的編碼格式和瀏覽器解析時(shí)的解碼格式不匹配導(dǎo)致的。
亂碼一般是英文以外的字符才會(huì)出現(xiàn)。

為啥純粹的英文不會(huì)出現(xiàn)亂碼問(wèn)題,即使編碼方式和解碼方式不一致?那是因?yàn)榍懊嬷v過(guò)了 utf-8、gbk對(duì)英文都是采用1個(gè)字節(jié)的編碼方式,并且使用了相同的碼字。
參考
百度百科
知乎

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容