輕松解決網站(zhàn)亂碼現(xiàn)象。相(₽αxiàng)信各位同行(xíng)或多(duō)或少(shǎo)都(d★&φōu)會(huì)碰到(dào)過亂碼的(de)問(wèn)題。從(cón∑"g)來(lái)沒有(yǒu)?相(xiàng)信我,β'•隻是(shì)時(shí)候未到(dào),在這(zhè)行(xíβ€ng)混,遲早會(huì)碰到(dào)的♠&(de)。當然,如(rú)果你(nǐ)對(duì)各類編碼非βδ常了(le)解,對(duì)浏覽器(qì)脾氣摸得(de)很(hěn)清楚了(☆∏↓©le),你(nǐ)可(kě)以避開(kāi)或者快(k★♦uài)速解決此類問(wèn)題。希望這(zhè)篇文(wén)章(zhān'↕ ≤g)對(duì)你(nǐ)有(yǒu)所幫助。
一(yī)、為(wèi)什(shén)麽會>¥≤↕(huì)出現(xiàn)亂碼?
在計(jì)算(suàn)機(jī)中 •,我們儲存的(de)信息都(dōu)是(shì)用(yòng)二進制(σ✘'zhì)碼表示的(de)。我們文(wén)字和(hé)符号用(yòng)的↑÷α(de)二進制(zhì)代碼的(de)互相(xiàng)<轉換,就(jiù)是(shì)編碼,轉換需要(yào)一(yī)種♥ ₽規則,就(jiù)是(shì)字符集(c∑<harset),我們常用(yòng)的(de)字符集例如(rú):÷<←ascii,gb2312,unicode。
不(bù)同的(de)字符集所存儲的(de)內(nèi) $¶¶容不(bù)同,比如(rú)&ldquo♦πλ;太平洋”三個(gè)字采用(yòng)gb2312對(duì∞∑β€)應的(de)值為(wèi)4411382949♠•83,utf-8對(duì)應為(wèi)E5A4AAE5B9B3E6B¶€•∞48B,這(zhè)樣,當一(yī)個(gè)gb2312的(de)文(w↔₽₩én)件(jiàn)嵌入一(yī)個(g™∑è)utf-8的(de)文(wén)件(ji®≥¥≤àn)的(de)時(shí)候,問(wèn)題就( ≥∏jiù)來(lái)了(le)。
二、ANSI,Unicode,UTF-8,Encod© <↔e,Charset,HTML實體(tǐ)&hell">♥♥ip;我快(kuài)瘋了(le)
瘋完了(le)沒,沒昏就(jiù)行(x€₩₹Ωíng)了(le),别著(zhe)急,聽(tīng)我一(yī)一(yī)道(♦←→dào)來(lái)。其實這(zhè)隻是(∏↓∏shì)同一(yī)樣東(dōng)西(xī)π∏σ₩在不(bù)同場(chǎng)合的(de)應用(yòng)。
A.ANSI,Unicode,UTF-8
這(zhè)幾個(gè)歸為(wèi)一£δ₽(yī)類,它們是(shì)文(wén)件(jiàn)編碼。δ§
ANSI指當地(dì)編碼,比如(rú)在大(dà)陸它指GB2312↕☆,在台灣它指GBK(Win中記事(shì)本保存↕↑$÷文(wén)件(jiàn)的(de)時(shí)候的(©∞'de)默認選項就(jiù)是(shì)它)。
Unicode是(shì)一(yī)個®¶₹λ(gè)通(tōng)用(yòng)字符集,它是(shì)一(yī)個δ (gè)編碼标準,這(zhè)個(gè) &≠和(hé)GB2312是(shì)對(duì)應的(de),♦∞₩♥但(dàn)因為(wèi)字符集過大(dà),Unicode有(y©™♣≤ǒu)它的(de)特殊性,在不(bù)同應用(yòng)場(chǎng)合,®®有(yǒu)不(bù)同的(de)具體(tǐ)實現(xiàn)手法,比如§(rú)應用(yòng)于互聯網傳輸,采用(yòng)的(de)∏ε§₽存儲與傳送格式是(shì)UTF-8,Windows應用(y&φòng)UTF-16,Linux應用(yòng)$♥φUTF-32。
B.Charset
HTML中的(de)Charset,CSS中的(de)@charset,↑÷✔&XML中的(de)encoding等,這φσ(zhè)幾個(gè)歸為(wèi)一(yī)類。
它們是(shì)告訴浏覽器(qì)如( "rú)何解碼。比如(rú)psd後綴是(shì)告訴系統這(zhè)∞ ₽是(shì)Photoshop源文(wén)件(jiàn),同樣charset≈♥設為(wèi)gb2312是(shì)告訴浏覽器(qì)這(zhè)是(sh ♠≈ì)一(yī)個(gè)簡體(tǐ)中文(wén)的(deΩ→)網頁。
C.Encode
Encode和(hé)encodeURI,encodeURICo≥€✔∏mponent歸為(wèi)一(yī)類。
這(zhè)在下(xià)一(yī)節中進行(xíng↔<₹∏)比較詳細的(de)介紹。當浏覽器(qì)提€✔交數(shù)據給服務器(qì)時(shí),特殊字符中文(w ♣★δén)一(yī)般浏覽器(qì)會(huì)"✘€§自(zì)動編碼,但(dàn)存在部分(f∑∑ēn)保留字符,比如(rú)”#/”等,這(zhè)←γ時(shí)候需要(yào)encode等進行(xíng)轉換。
D.HTML實體(tǐ)
當網頁中需要(yào)插入某些(xiē)特殊字符♥'∏✘時(shí),需要(yào)用(yòng)到σ •(dào)HTML實體(tǐ),比如(rú)★插入<,可(kě)以使用(yòng)<或者實體(tǐ) ₽±σ編碼<。
三、JavascriptURI編碼/解碼
A.為(wèi)什(shén)麽需要(yào)U¥×π↔RI編碼?
通(tōng)常來(lái)說(shuō),之所以URI需要♥<$(yào)進行(xíng)編碼,是(shì)因為(wèi)φ¶ εURI中有(yǒu)些(xiē)字符可(kě)能(nén™♥g)會(huì)引起歧義或者有(yǒu)隐私的(de)數(shù)據。
B.編碼與解碼的(de)函數(sh> ù)?
JS對(duì)文(wén)字進行(xíng)βα£編碼涉及3個(gè)函數(shù):escape,encodeU ×RI,encodeURIComponent,相(xiε≥∏¶àng)應3個(gè)解碼函數(shù):unesΩ✘<cape,decodeURI,decod↓₩eURIComponent
C.如(rú)何選擇?
首先,範圍不(bù)同。Escape不(bù)能$λ∞↑(néng)編碼的(de)字符有(yǒu):@*/+;encodeURI ≤:!@#$&*()=:/;?+‘'₹∑;encodeURIComponent:!*()。
其次,編碼類型不(bù)同。encodeURI、encodeUR≠∏IComponent采用(yòng)utf-8進行(xλ"₽¶íng)編碼;而Escape采用(yòng)系¶π$統編碼。
所以,怎麽選擇?例如(rú)內(nèi₽☆)容中要(yào)存在URI标識,則用(yòng)encodeUR$♣ €I,如(rú)果想把”#,/”也(yě)要♦ε≈÷(yào)編碼用(yòng)escape或e ☆€ncodeURIComponent。
四、Ajax加載的(de)文(wé≥βn)件(jiàn)中不(bù)能(néng)↑★©用(yòng)中文(wén)?
這(zhè)一(yī)直是(shì)讓開(kāi)發人(rén)員(yu♣•¶án)很(hěn)頭疼的(de)問(wè↕¶n)題之一(yī),也(yě)是(shì)常見(ji"™φàn)的(de)編碼問(wèn)題,原因很↓β(hěn)簡單,你(nǐ)非得(de)拿(ná)羊城(chéng)通(₩δ÷tōng)往ATM上(shàng)插,結果當然₹♠↑是(shì)讀(dú)不(bù)出來(lái)或者讀(dú)錯(cuò)¥ 。編碼問(wèn)題也(yě)是(shì)一(yī)樣,通(tōng)常出錯(×π€cuò)的(de)情況是(shì),文(wé≤δn)檔編碼是(shì)GB2312,而浏覽器(qì)以UTF-8(Ajax默認♣☆解碼方式)來(lái)解碼,自(zì)然亂碼。
怎麽解決呢(ne)?
1、文(wén)檔采用(yòng)UTF-8編碼,不★↑¥'(bù)會(huì)産生(shēng)任何問(wèn)題。
2、如(rú)果不(bù)能(néng)用(yòng)UTF-8♥σ→,XML文(wén)檔可(kě)以指定它的(d$<e)Encoding,JS文(wén)件(jiàn)和(hé)JSON數(sh•✘→φù)據目前沒有(yǒu)好(hǎo)的(de)解決辦¶≠©法。
五、GB2312,UTF-8都(dōu)可(kě)以顯示中文(w ₽én),如(rú)何選擇?
可(kě)以顯示中文(wén)的(de)編碼<₽有(yǒu)GB2312、GBK、GB18030、Unicode。前✔£↔$三個(gè)保持向後兼容,比如(rú)“
邯鄲網站(zhàn)建設”這(zhè)幾個(gè)字在這(zhè)幾個≠±(gè)編碼規則中內(nèi)碼是(shì)一(yī)樣的(de)。它們的(™δde)不(bù)同之處在于字符集不(bù)同,GB2312隻包括簡體(↓≈tǐ)中文(wén),GBK還(hái)包括繁體(tǐ),Ω♦♣GB18030再加入了(le)少(shǎγ₽☆o)數(shù)民(mín)族語言,比如(rú)藏文(wén)。那(nà)→☆如(rú)果顯示簡體(tǐ)中文(wén)可(kě♠≤♣)以任意選擇?據我目前測試了(le)解,應該都(dōu)是(shì)可(kě₹→ σ)以的(de),至于速度上(shàng)是(shì)否有(yǒu)差異,↓✘還(hái)未深究,但(dàn)GB2312肯定更≤☆ 為(wèi)通(tōng)用(yòng)₽↔♣→,而且據我測試已經包含了(le)相(xià ∏§ng)當部分(fēn)繁體(tǐ)。至于Unicod ÷e,應用(yòng)在網頁中的(de)UTF-8,™≥中文(wén)一(yī)般需要(yào)占據3個(gè)字節≠£δ•(前三種2個(gè)字節),所以當中文(wén)較多(duōδ<↑)的(de)網頁用(yòng)UTF-8文(wén)件(↕"★₽jiàn)将變得(de)更大(dà)(我們公∞¥司大(dà)部分(fēn)網頁4%左右)。
六、UTF-8、UTF-16、UTF->"32什(shén)麽區(qū)别?
Unicode所做(zuò)的(de)是(shì)為(wèi)每個 ↑¶£(gè)字符定義了(le)一(yī)個(gè)相(xiàng)應的(de)數(×∞≤shù)字表示。比如(rú),“a“的(d×♦$e)Unicode值是(shì)0×0061,&•¥↑ldquo;一(yī)”的(de)Unicde值是(shì)0&t"™imes;4E00,這(zhè)是(shì)最簡單的(de)情況,每個( ↓↓gè)字符用(yòng)2個(gè)字節表示。Un↕↔icode定義了(le)百萬個(gè)以上(shàng)的(de)字∑₩≠>符,如(rú)果将所有(yǒu)的(de)字符用(yòng)統一(yī)←¥的(de)格式表示,需要(yào)的(de)是(shì)4個(gè)字節。뮥“a“的(de)Unicode表示就(→Ωαjiù)會(huì)變成0×00000061,而“←§≈£一(yī)“的(de)Unicode值是(shì)0&tiγπ mes;00004E00。實際上(shàng),這(zhè)就(jiù)是(sβδ™hì)UTF32,Linux操作(zuò)≥¥系統上(shàng)所使用(yòng)的(de)Uni¶↓&÷code方案。但(dàn)是(shì),仔細分(fēn)析可(kě)以發<↕現(xiàn),其實絕大(dà)部分(fēn)字符隻使用(π✘®₽yòng)2個(gè)字節就(jiù)可(kě)以表示了(le)。英文(w >én)的(de)Unicode範圍是(shì)0שα≈♥0000-0×007F,中文(wén)的(π≠de)Unicode範圍是(shì)0×4E00¶≥×↓-0×9F**,真正需要(yào)擴展到(dào)4個(gè)字節¥€☆↑來(lái)表示的(de)字符少(shǎo)之又(yòu)少(shǎoβ♥&),所以有(yǒu)些(xiē)系統直接使用(yòng)2個(gè)字節€ 來(lái)表示Unicode。比如(rú)Windows系統上(shàng)≈λ∏Ω,Unicode就(jiù)是(shì)兩個(gè)字節的<'(de)。對(duì)于那(nà)些(xiē)需要(yào)4個(gè∞§)字節才能(néng)表示的(de)字符,使用(yòng)一(yī)±÷×種代理(lǐ)的(de)手法來(lái)☆®★<擴展(其實就(jiù)是(shì)在低(dī)兩個(gè)字≥♥∞☆節上(shàng)做(zuò)一(yī)個(gè)标記,表∑φ示這(zhè)是(shì)一(yī)個(gè)代理(lǐ),需要(✔λ≈↕yào)連接上(shàng)随後的(de)兩個(gè¶€)字節,才能(néng)組成一(yī)個(gè)♥¶γ字符)。這(zhè)樣的(de)好(hǎo)處是(shì✘ ♣)大(dà)量的(de)節約了(le)存取空(kōng∑¥≈→)間(jiān),也(yě)提高(gāoΩφ)了(le)處理(lǐ)的(de)速度。這(zhè)種Unic§≥∑↔ode表示方法就(jiù)是(shì)UTF16。一(yī)般在Window±↔♣s平台上(shàng),提到(dào)Unicode,那(nà©&£ )就(jiù)是(shì)指UTF16了(l∑"e)。而UTF-8更有(yǒu)意思,它的(de)字節✔$×數(shù)1-4個(gè)不(bù)等β,如(rú)果純英文(wén)的(de)應用(yòn♠φ"g)環境,自(zì)然用(yòng)它更φ<加節省。
七、CSS、JS的(de)編碼可(kě)以和(hé)HTML不(b±εù)一(yī)緻嗎(ma)?
可(kě)以。但(dàn)最好(hǎo)在引用(yòπ₹ng)時(shí)手動設置Charset,值得(de)注意的(d e)是(shì)IE、FF默認根據當前頁↔ ♠面編碼,而Chrome默認是(shì)UTF-8。♠↓