在Content-Type 标头中没有明确的charset 属性的情况下,通过不同传输方式发送的不同媒体类型具有不同的默认字符集。
例如,仅显示一些定义:
RFC 2046,MIME 规范的4.1.2 部分说:
与其他一些参数值不同,charset 参数的值不区分大小写。 默认字符集(在没有字符集参数时必须假定)是 US-ASCII。
RFC 2616,HTTP 协议规范的3.7.1 部分说:
“charset”参数用于某些媒体类型来定义数据的字符集 (section 3.4)。 当发送方未提供明确的字符集参数时,“文本”类型的媒体子类型被定义为在通过 HTTP 接收时具有默认字符集值“ISO-8859-1”。除“ISO-8859-1”或其子集以外的字符集中的数据必须用适当的字符集值标记。有关兼容性问题,请参阅section 3.4.1。
后来被RFC 7231、Appendix B逆转:
已删除文本媒体类型的默认 ISO-8859-1 字符集;现在的默认值就是媒体类型定义所说的。同样,从 Accept-Charset 标头字段中删除了对 ISO-8859-1 的特殊处理。 (Section 3.1.1.3 和 Section 5.3.3)。
XML 媒体类型规范的RFC 3023、3.1、3.3、3.6 和 8.5 部分说:
符合 [RFC2046],如果接收到的 text/xml 实体省略了 charset 参数,MIME 处理器和 XML 处理器必须使用默认的 charset 值“us-ascii”[ASCII]。在 XML MIME 实体通过 HTTP 传输的情况下,默认字符集值仍然是“us-ascii”。 (注意:此规范与 HTTP/1.1 存在不一致,由于历史原因,HTTP/1.1 使用 ISO-8859-1[ISO8859] 作为默认值。由于 XML 是一种新格式,因此应选择新的默认值以获得更好的 I18N。选择了 US-ASCII,因为它是 UTF-8 和 ISO-8859-1 的交集,并且已经被 MIME 使用。)
text/xml-external-parsed-entity 的 charset 参数的处理方式与 Section 3.1 中描述的 text/xml 相同。
以下列表适用于根据本规范定义字符集参数的顶级类型“text”下的 text/xml、text/xml-external-parsed-entity 和基于 XML 的媒体类型:
...
- 如果不指定charset参数,默认为“us-ascii”。 HTTP 中“iso-8859-1”的默认值被显式覆盖。
此示例显示省略了 charset 参数的 text/xml。在这种情况下,MIME 和 XML 处理器必须假定字符集是“us-ascii”,这是 [RFC2046] 中指定的文本媒体类型的默认字符集值。 即使 text/xml 实体使用 HTTP 传输,“us-ascii”的默认值仍然有效。
不建议对 text/xml 省略 charset 参数。例如,即使 XML MIME 实体的内容是 UTF-16 或 UTF-8,或者 XML MIME 实体有明确的编码声明,XML 和 MIME 处理器必须假定字符集是“us-ascii”。
RFC 7159,8.1 和 11 部分,JSON 规范说:
JSON 文本应以 UTF-8、UTF-16 或 UTF-32 编码。默认编码为 UTF-8,以 UTF-8 编码的 JSON 文本是可互操作的,因为它们将被最大数量的实现成功读取;有许多实现无法成功读取其他编码(如 UTF-16 和 UTF-32)的文本。
实现不得在 JSON 文本的开头添加字节顺序标记。为了互操作性,解析 JSON 文本的实现可能会忽略字节顺序标记的存在,而不是将其视为错误。
注意:没有为此注册定义“charset”参数。添加一个确实对合规收件人没有影响。
因此,一般来说,如果您想知道给定资源使用的字符集,并且该字符集不是通过外部方式表达的,例如 Content-Type 标头的 charset 属性,那么您必须确定什么您正在处理的数据类型,然后根据该数据类型的规范概述确定其字符集。
在您的情况下,您正在通过 HTTP 处理 HTML,因此 RFC 2616 规则适用于您。 HTML 5 spec,8.2.2.2 部分定义了一个非常详细的算法,用于在 Content-Type 标头中未指定 charset 属性时确定 HTML 的字符集。该算法首先检查是否存在 UTF BOM,如果不存在则假定 HTML 是 8 位的,并解析它以查找包含字符集或语言声明的任何 <meta> 标记。
XML 1.0 specification、Appendix F 还定义了一种算法,可以很容易地确定 XML prolog 使用的字符集,因此您可以读取它的 Encoding 属性(如果存在)来确定剩下的 XML。