根据 HTML4.01 规范中的描述,服务端应该提供给用户端文档的字符编码(character encoding)信息,最直接的方式为通过 HTTP 协议([RFC2616], 3.4 及 14.17) "Content-Type" 头字段的 "charset" 将文档的字符编码告诉用户端。例如以下 HTTP 头声明了字符编码为 ISO-8859-1:
Content-Type: text/html; charset=ISO-8859-1
处于某种情况无法访问服务器时,HTML 文档可以包含有关文档的字符编码的明确信息,META 元素可以用来为用户端提供这些信息。例如指定当前文档的字符编码为 ISO-8859-1,文档中应包含如下 META 声明:
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
当 HTTP 协议与 META 元素均没有提供有关一个文档的字符编码信息时,HTML 还为一些元素提供了 charset 属性。结合这些机制,作者可以在很大程度上提高当用户获取资源时用户端识别字符编码的机会。
针对如何确定一个文档的字符编码,用户代码必须遵守下面的优先级顺序(优先级由高至低):
关于 字符编码 的详细信息,请参考 HTML4.01 规范 5.2 Character encodings 以及 W3C Internationalization 关于 Character encodings 中的内容。
各浏览器对于字符编码别名支持的宽泛程度有差异,当指定了浏览器无法识别的字符编码别名时,浏览器会以确定编码的优先级顺序采用设置的更低优先级的字符编码,以此类推。
而 Chrome Safari Opera 中对字符编码别名有着比其他浏览器更宽泛的支持。
若字符编码别名设置不当,则会造成页面在某些浏览器中出现文字编码错误,导致页面无法阅读。
所有浏览器 |
---|
我们通常情况下为页面设定的字符编码信息所指对应到浏览器内部大多是字符编码别名,如 ISO-8859-1。
首先分析当 HTTP "Content-Type" 头字段的 "charset" 参数与页面中 META 元素声明中 "http-equiv" 为 "Content-Type" 对应的值中的 "charset" 的值不同时各浏览器所采用的字符编码。
分析以下代码:charset.php
<?php header("Content-Type: text/html; charset=BIG5"); ?> <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> </head> <body> <script> document.write((document.charset || document.characterSet).toUpperCase()); </script> </body> </html>
上面是一段 PHP 代码,HTTP "Content-Type" 头字段设置了字符编码为 BIG5,页面中的 META 元素设置了字符编码为 UTF-8,页面本身的编码类型为 GB2312。页面执行时,通过脚本输出了当前浏览器所采用的字符编码类型。
这个动态页面在各浏览器中运行时均显示出了 BIG5,可见此时所有浏览器均遵照 HTML4.01 规范所述,以更高优先级的 HTTP "Content-Type" 头字段的 "charset" 参数的值作为字符编码类型。
关于 document.charset 和 document.characterSet 的详细信息,请参考 MSDN charset Property 与 MDC document.characterSet 中的内容。
在继续接下来的分析之前,先统计一下各浏览器对于没有任何字符编码设定的页面所采用的编码类型:default_charset.html
<!DOCTYPE html> <html> <head> </head> <body> <script> document.write((document.charset || document.characterSet).toUpperCase()); </script> </body> </html>
上面页面中没有设定任何的字符编码信息,则各浏览器对于这个页面将使用各自的默认编码1。页面自身的编码为 GB2312。
各浏览器中运行效果如下:
IE6 IE7 IE8 Firefox | Chrome Safari | Opera |
---|---|---|
字符编码 --- GB2312 | ×Ö·û±àÂë --- ISO-8859-1 | 字符编码 --- GBK |
可以看到各浏览器对页面的默认字符编码不尽相同。
当页面没有设置任何字符编码信息或者浏览器无法识别 HTTP 头字段以及 META 元素中所声明的字符编码信息时,所有浏览器均会以各自在当前语言版本下的默认字符编码显示页面。
本例中,因为页面自身的编码为 GB2312,则 Windows 平台下 IE Firefox Opera 简体中文版的默认字符编码刚好为
GB2312,所以页面中的字符显示正常。
注 1:操作系统及浏览器语言均为简体中文。
下面看一组特殊的例子:charset-x.php
<?php header("Content-Type: text/html; charset=maccyrillic"); ?> <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=b.i.g+5"/> </head> <body style="font:24px Tahoma;"> 字符編碼 --- <script> document.write((document.charset || document.characterSet).toUpperCase()); </script> </body> </html>
上面的动态页面自身的编码为 BIG5,HTTP "Content-Type" 头字段设置了字符编码为 maccyrillic,页面中的 META 元素设置了字符编码为 b.i.g+5。
各浏览器中运行效果如下:
IE6 IE7 IE8 Firefox | Chrome Safari | Opera |
---|---|---|
才絪絏 --- GB2312 | ¶r≤≈љsљX --- X-MAC-CYRILLIC | 字符編碼 --- BIG5 |
出现上述现象的原因主要有三点:
注 1:各浏览器均可以识别 X-MAC-CYRILLIC 这种通用的字符编码别名。
首先,对于动态页面必须确保 HTTP "Content-Type" 头字段的 "charset" 参数与页面自身编码相符,且务必在页面的 META
元素中也声明相符的字符编码信息。对于静态页面,必须保证页面中 META 元素声明中 "http-equiv" 为 "Content-Type" 对应的值中的
"charset" 的值与页面自身编码相符。
其次,在设置字符编码别名时,最好使用最通用的、各浏览器均可识别的编码别名。
下面列出了部分的字符编码及其推荐的通用的别名在各浏览器中的支持情况:
标准字符编码名 | 推荐的字符编码别名 | ||||||||
---|---|---|---|---|---|---|---|---|---|
名称 | 各浏览器测试 | 名称 | 各浏览器测试 | ||||||
IE6 IE7 IE8 | Firefox | Chrome Safari | Opera | IE6 IE7 IE8 | Firefox | Chrome Safari | Opera | ||
ANSI_X3.4-1968 | US-ASCII | US-ASCII | US-ASCII | WINDOWS-1252 | US-ASCII | US-ASCII | US-ASCII | US-ASCII | WINDOWS-1252 |
ISO_8859-1:1987 | ISO-8859-1 | 不识别 | ISO-8859-1 | WINDOWS-1252 | ISO-8859-1 | ISO-8859-1 | ISO-8859-1 | ISO-8859-1 | WINDOWS-1252 |
ISO_8859-2:1987 | ISO-8859-2 | 不识别 | ISO-8859-2 | ISO-8859-2 | ISO-8859-2 | ISO-8859-2 | ISO-8859-2 | ISO-8859-2 | ISO-8859-2 |
ISO_8859-3:1988 | ISO-8859-3 | 不识别 | ISO-8859-3 | ISO-8859-3 | ISO-8859-3 | ISO-8859-3 | ISO-8859-3 | ISO-8859-3 | ISO-8859-3 |
ISO_8859-4:1988 | ISO-8859-4 | 不识别 | ISO-8859-4 | ISO-8859-4 | ISO-8859-4 | ISO-8859-4 | ISO-8859-4 | ISO-8859-4 | ISO-8859-4 |
ISO_8859-5:1988 | ISO-8859-5 | 不识别 | ISO-8859-5 | ISO-8859-5 | ISO-8859-5 | ISO-8859-5 | ISO-8859-5 | ISO-8859-5 | ISO-8859-5 |
ISO_8859-6:1987 | ISO-8859-6 | 不识别 | ISO-8859-6 | ISO-8859-6 | ISO-8859-6 | ISO-8859-6 | ISO-8859-6 | ISO-8859-6 | ISO-8859-6 |
ISO_8859-7:1987 | ISO-8859-7 | 不识别 | ISO-8859-7 | ISO-8859-7 | ISO-8859-7 | ISO-8859-7 | ISO-8859-7 | ISO-8859-7 | ISO-8859-7 |
ISO_8859-8:1988 | ISO-8859-8 | 不识别 | ISO-8859-8 | ISO-8859-8 | ISO-8859-8 | ISO-8859-8 | ISO-8859-8 | ISO-8859-8 | ISO-8859-8 |
ISO_8859-9:1989 | ISO-8859-9 | 不识别 | WINDOWS-1254 | ISO-8859-9 | ISO-8859-9 | ISO-8859-9 | ISO-8859-9 | WINDOWS-1254 | ISO-8859-9 |
ISO-8859-10 | 不识别 | ISO-8859-10 | ISO-8859-10 | ISO-8859-10 | ISO-8859-10 | 不识别 | ISO-8859-10 | ISO-8859-10 | ISO-8859-10 |
更多请参见 IANA CHARACTER SETS 及 RFC1345。
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6.8 Chrome 6.0.472.25 dev Safari 5.0.1 Opera 10.60 |
测试页面: |
charset.php
default_charset.html charset-x.php |
本文更新时间: | 2010-08-12 |
content-type meta charset 字符集 元数据 编码