PHP前端开发

HTML5标准学习-编码详解

百变鹏仔 6个月前 (10-18) #H5教程
文章标签 详解

相信每一个前端工程师都或多或少遇上过“乱码”这位仁兄,无论你的基础有多么扎实,在生产的过程中都免不了偶尔和“乱码”兄弟喝上几杯茶吧。作为一个前端工程师,你是如何指定一个页面的编码的呢?你知道浏览器是怎么识别编码的吗?

首先,一个很简单的例子,用遇简的HTML页面来看看各浏览器下有什么不同:

<!DOCTYPE html>

最简HTML,和都没有内容,服务器也不给出具体的编码声明,直接从本地打开,各个浏览器下查看页面的编码:

浏览器显示编码备注
IE6UTF-8
IE8UTF-8
IE9GB2312系统默认字符集
Firefox3.5GBK2312系统默认字符集
Firefox4.0ISO-8859-1西欧语言,英语默认编码
ChromeGBK系统默认字符集
Opera中文-自动检测应该也是GB2312

从表格中可以看出,对于没有使用任何手段声明编码的页面,各浏览器有着不同的解析。当然在最简的页面中,无论用什么编码(当然前提是ASCII的超集)都没有影响,但足以表现出正确设置编码的重要性。

编码声明

HTML4和HTML5分别采用了一个章节来阐述编码声明的方法,可以点击这里查看HTML4的相关章节或点击这里查看HTML5的相关章节。

立即学习“前端免费学习笔记(深入)”;

首先,何为编码?编码即是通过一定的方式,指定浏览器(或称用户代理)以一种特殊的算法来解析字节流,以得到真正正确的内容。在HTML的标准中,编码可以使用别名来表示。编码的别名来自于IANA的定义,只有在该列表中出现的编码才可以被浏览器识别。因此如果把UTF-8写成UTF8,浏览器就有可能完全不予理睬。另外,编码别名是大小写不敏感的。

在HTML4中,提出有3种方法指定页面的编码,根据优先级高低依次是:

  1. HTTP头里的Content-Type字段后跟随字符集。

  2. 使用标签来声明。

  3. 对于部分外部资源,如标签加载的js文件,可以通过标签上的charset属性声明。

这个自然没有什么疑问,需要注意的是,通过标签来声明页面的话,当浏览器遇上该标签时,如果发现自己使用的编码与标签声明的不符,是会回到头里重新解析页面的。这会导致页面的一部分被重新解析,因此如果试图使用标签的方式声明编码的话,建议将标签尽可能地写在前面。一个最佳实践是写在标签之后,任何其他标签之前。关于这一点,Google PageSpeed也有相应的介绍。

时代演进

但是随着时间的推移,开发者渐渐发现了一件事。就如同DOCTYPE的最简声明一样,其实浏览器在读取标签的编码的时候,并不是严格地按照标准进行的。总而言之,由于在HTML的解析阶段,基于在Tokenizer阶段之前就必须确定好页面的编码,因此浏览器不可能像分析DOM树一样,在DOM树构建的时候再分解标签的结构,取出其中的http-equiv和content属性,再确定编码。

现实中,浏览器做了一件非常简单的事,来读取标签定义的编码:

  1. 确定这是一个标签,这根据HTML解析的状态机,由"