为什么python json解码器会抛出带有UTF-16 BOM的字符串?



挖掘python json解码器实现我注意到,如果将字符串传递给json.loads并且它以ufeff开头,这是一个UTF-16 BOM,它会引发一个JSONDecodeError

if isinstance(s, str):
if s.startswith('ufeff'):
raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", s, 0)

(GitHub(

RFC3629(UTF-8 之一(说明了两种应该禁止使用 UTF-16 BOM 的情况,但似乎都不适用于 JSON:

o 协议应禁止使用 U+FEFF 作为签名 协议要求始终的文本协议元素 UTF-8,签名函数在那些中完全无用 例。

o 协议还应禁止使用 U+FEFF 作为 协议提供的那些文本协议元素 字符编码识别机制,当预期时 协议的实现将能够 始终正确使用这些机制。 当 协议元素在 从创建到实施 它们的(正确标记的(传输。

RFC7159(JSON的(说:

JSON 文本应以 UTF-8、UTF-16 或 UTF-32 编码。 这 默认编码为 UTF-8,以及以 UTF-8 编码的 JSON 文本 在可互操作的意义上,它们将被成功读取 按最大实现次数;有很多 无法成功读取其他文本的实现 编码(如 UTF-16 和 UTF-32(。

所以在我看来,应该允许使用 UTF-16。那么为什么Python会在这里提出呢?显然我错过了一些东西。

来自当前最新的 JSON RFC:

实现不得在网络传输的 JSON 文本的开头添加字节顺序标记 (U+FEFF(。 为了互操作性,解析 JSON 文本的实现可能会忽略字节顺序标记的存在,而不是将其视为错误。

类似的语言也出现在 RFC 7159 中。

JSON 实现不需要接受字节顺序标记。Python的实现没有。如果要将带有字节顺序标记的 JSON 传递给 Python 的 JSON 解析器,则应在早期处理阶段删除 BOM。

最新更新