一、为什么会出现乱码?
在计算机中,我们储存的信息都是用二进制码表示的。我们文字和符号用的二进制代码的互相转换,就是编码,转换需要一种规则,就是字符集(charset),我们常用的字符集例如:ascii,gb2312,unicode。简单说,字符集只是指定了一个集合中有哪些字符,而字符编码,是为这个集合中所有字符定义个编号。
计算机中只保存该字符在某字符集中对应的字符编号(也叫字符编码),计算机只需要维持一份字符集清单,当读到这种编号值(编码),就在对应字符清单中找出该字符显示出来即可。字符大小颜色都是程序按照字符样式绘制而成的。
怎么样读取文件并正确显示文件内容?
下面以“中国”为例(中文简体windows):
以下以:“abc”为例
1.以某字符集存储字符时,它会在该字符集中搜索这个字符的位置(编号或编码),以这个编号(编码)保存在文件,如果所搜找不到该字符,一般会以:3F 3F保存(一定会出错)
2. 当需要显示字符,从取文件中字符编码,如果没有指定字符集,会通过文件头(主要unicode字符集有特殊头标记)判断字符集,如果不是unicode字符集,默认都以ANSI字符集读取,用字符编码在该字符集中寻找对应字符,如果搜索到就正常显示,搜索不到就会显示乱码.
3,最常见的网页乱码是当一个gb2312的文件嵌入一个utf-8的文件的时候,到底该识别成什么或者是转换成什么?于是乱码就来了。
二、 编码知识
ANSI字符集 :
其实ANSI指当地编码,比如在大陆简体中文windows它指GB2312,在台湾它指GBK
在日文操作系统下,ansi 编码代表 JIS 编码
GB18030, GBK,GB2312, big5关系
可以显示中文的编码有GB2312、GBK、GB18030、Unicode。Unicode暂先不讨论。
简单说说其他几个的兼容关系,依次是GB18030完全兼容 GBK,GBK完全兼容了GB2312,兼容的含义是不仅字符兼容,而且相同字符的编码也相同
比如“太平洋”这几个字在这几个编码规则中内码是一样的。它们的不同之处在于字符集不同,GB2312只包括简体中文,GBK还包括繁体,GB18030再加入了少数民族语言,比如藏文, 而Big5只是台湾标准,是繁体中文代表,目前bug5和gb2312不能通过程序相互转化,需要有字符集映射关系才能完成。
unicode与utf-8 、utf-16 utf-32是什么关系?
unicode(统一码)是一种字符集,每一种语言的不同的编码页,增加了那些需要支持不同语言的软件的复杂度。因而人们制定了一个世界标准,叫做unicode。unicode为每个字符 提供 了唯一的特定数值,不论在什么平台上、不论在什么软件中,也不论什么语言。也就是说,它世界上使用的所有字符都列出来,并给每一个字符一个唯一特定数值。
UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。在Unicode中:汉字“字”对应的数字是23383。我们可以用:UTF-8、UTF-16、UTF-32表示这个数字,将数字23383存储在计算机中。UTF-8对应是:0xE6, 0xB1, 0x89(3个字节),UTF-16对应是:0x6c49(2个字节),UTF-32对应是:0x6c49(4个字节)。utf-8,utf-16,utf-32是unicode码一种实现形式,都是属于unicode编码。
不同编码的适用性:
1.GBK的文字编码是双字节来表示的,不论中,英字符均使用双字节来表示
UTF-8编码则对英文使用一个字节,对中文使用3个字节,所以对于英文字符较多的网站一般使用utf-8来节省空间
2.因为字符集过大,Unicode有它的特殊性,在不同应用场合,有不同的具体实现手法,比如应用于互联网传输,采用的存储与传送格式是UTF-8
但在国际文档(txt和xml)使用unicode编码是正宗做法;操作系统和浏览器都能够“理解”unicode编码。
3. UTF-8包含全世界所有过节要用到的字符,UTF-8编码的文字可以在各国各种支持UTF8字符集的浏览器上显示,比如,如果是UTF8编码,则在外国人的英文IE上也能显示中文,而无需他们下载IE的中文语言支持包。浏览器“迫于压力”才“理解”utf-8编码。但是,操作系统有时只认unicode编码。
三、后面是其他人总结的关于浏览器编码纠错
测试:创建utf-8文件,更改meta charset属性为gb2312(文件本身数据编码不变),外链gb2312的JS文件,结论:
IE&Chrome自动以utf-8解析,外链JS乱码;
FF以gb2312解析,外链JS中文显示正常。Demo: 测试自动解析编码.html
3、Ajax加载,如果目标文档文件编码非UTF-8,需指定encoding,否则中文乱码;
XML是可以指定编码的,但如果是JSON,Script之类的数据,无法指定编码,要显示中文只有用UTF-8的编码;
4、外链的js,IE、FF默认根据当前页面编码,Chrome默认是Utf-8。如果JS文件为Unicode编码,给文件加上bom比较保险(IE、FF的智能识别)
5、Get数据,IE678,ff3 GBK编码,Chrome utf-8编码。