为什么python json解码器会抛出带有UTF-16 BOM的字符串?
通过深入研究python json解码器实现,我注意到如果一个字符串被传递到为什么python json解码器会抛出带有UTF-16 BOM的字符串?,python,json,encoding,utf-8,Python,Json,Encoding,Utf 8,通过深入研究python json解码器实现,我注意到如果一个字符串被传递到json.loads,并且它以\ufeff开头,这是一个错误,它会引发一个JSONDecodeError: if isinstance(s, str): if s.startswith('\ufeff'): raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", s, 0) () (UTF-8一)说明了两种情况
json.loads
,并且它以\ufeff
开头,这是一个错误,它会引发一个JSONDecodeError
:
if isinstance(s, str):
if s.startswith('\ufeff'):
raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", s, 0)
()
(UTF-8一)说明了两种情况下UTF-16 BOM应该被禁止,但它们似乎都不适用于JSON:
o协议应禁止使用U+FEFF作为这些协议的签名
协议要求始终保持的文本协议元素
UTF-8,签名功能在这些应用程序中完全无用
案例
o协议还应禁止使用U+FEFF作为
协议提供的那些文本协议元素
字符编码识别机制,当需要时
协议的实现将能够
始终正确使用机械装置。这种情况将在
协议元素在
从创建之时到发布之时的实施
它们的(正确标记的)传输
(JSON one)说:
JSON文本应采用UTF-8、UTF-16或UTF-32编码。这个
默认编码为UTF-8,JSON文本以UTF-8编码
从成功读取的意义上讲,它们是可互操作的
按实现的最大数量;有很多
无法成功读取其他文件中文本的实现
编码(如UTF-16和UTF-32)
所以在我看来,UTF-16应该被允许。那么为什么Python会在这里出现呢?很明显,我遗漏了一些东西。来自:
实现不得在网络传输的JSON文本的开头添加字节顺序标记(U+FEFF)。为了实现互操作性,解析JSON文本的实现可能会忽略字节顺序标记的存在,而不是将其视为错误
类似的语言也出现在电影中
接受字节顺序标记不需要JSON实现。Python的实现并没有这样做。如果要将带有字节顺序标记的JSON传递给Python的JSON解析器,则应该在早期处理阶段删除BOM。您似乎混淆了哪个RFC用于UTF-8,哪个用于JSON。另外,Python3
str
表示编码独立的Unicode。经过更多的阅读,它变得更加清晰。python json解析器拒绝它在accepted answer-spec中正确声明的BOM的主要原因是允许它这样做的,所以这个解析器会这样做。让我困惑的是,我认为有两个BOM,UTF-8和UTF-16,解析器拒绝了UTF-16一个,同时声明它拒绝了UTF-8一个。事实上,只有一个BOM,U+FEFF,\xef\xbb\xbf版本只是它的UTF-8编码。因此,我现在理解的代码背后的逻辑是:[续][续]:如果字符串以BOM开头,那么它必须是未剥离的UTF-8 one,因为如果它是UTF-16 one,它将在读取时剥离。如果它幸存下来,那么产生传递字符串的字节将被编码为UTF-8,并在不剥离BOM的情况下进行解码。这就是为什么异常也告诉“使用utf-8-sig解码”。这在我看来似乎是规范中的一个错误。U+FEFF
的正式定义不是字节顺序标记,而是一个。JSON应该像对待任何其他空白一样对待它。@markransem:JSON特别指出了“不重要的空白”中允许的四个空白字符:空格、水平制表符、换行符和回车符。字符串之外的其他空格是错误的。是的,它是错误的,我相信空格列表是不必要的限制。如果您只打算使用它的ASCII子集,那么为什么还要麻烦使用基于Unicode的呢?谢谢。这本身就回答了问题,但起初我还是感到困惑。事实上,您在关于编码独立Unicode的原始问题下的评论有助于澄清更多的问题!:)