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

时间:2018-04-30 19:11:38

标签: python json encoding utf-8

挖掘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会在这里加注呢?显然我错过了什么。

1 个答案:

答案 0 :(得分:2)

来自currently most recent JSON RFC

  

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

类似的语言也出现在RFC 7159

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