我一直在阅读RFC-4627规范,并开始进行解释:
在将有效载荷发布为application/json
mime-type时,
BOM
,而application/json; charset=utf-8
的mime类型 header 而不是符合RFC-4627(基于“6. IANA注意事项”部分)。 这些是正确的推论吗?在实现遵循此解释的Web服务或Web客户端时,我会遇到问题吗?是否应该针对违反上述两个属性的Web浏览器提交错误?
最佳答案
你是对的
RFC 7159, Section 8.1:
Implementations MUST NOT add a byte order mark to the beginning of a JSON text.
尽可能清楚地说明这一点。这是整个RFC中唯一的“不得”。
RFC 7159, Section 11:
The MIME media type for JSON text is application/json.
Type name: application
Subtype name: json
Required parameters: n/a
Optional parameters: n/a
[...]
Note: No "charset" parameter is defined for this registration.
JSON编码
JSON的唯一有效编码是UTF-8,UTF-16或UTF-32,并且由于第一个字符(如果有多个字符,则为前两个字符)的Unicode值始终小于128(没有有效的JSON)可以包含前两个字符的较高值的文本),总是有可能仅通过查看字节流就知道使用了哪种有效编码以及使用了哪种字节序。
RFC建议
JSON RFC表示前两个字符将始终在128以下,并且您应检查前4个字节。
我用不同的说法:因为字符串“1”也是有效的JSON,所以不能保证您有两个字符-更不用说4个字节了。
我的建议
我对确定JSON编码的建议会稍有不同:
快速方法:
(实际上,这里唯一有效的字符是ASCII数字)
(必须是不带前导“0”,
{}
,[]
或""
的ASCII数字)(必须是编码为UTF-16,大端的ASCII数字)
(必须为ASCII数字,编码为UTF-16,小端)
(同样,不带前导0的ASCII数字,
"x"
,[1]
等。)00 00 00 xx
-它是UTF-32BE 00 xx 00 xx
-这是UTF-16BE xx 00 00 00
-它是UTF-32LE xx 00 xx 00
-它是UTF-16LE xx xx xx xx
-它是UTF-8 但只有在这些编码中的任何一个确实是有效字符串(如果不是)时,它才有效。而且,即使您具有5种有效编码之一中的有效字符串,它也可能不是有效的JSON。
我的建议是进行比RFC所包含的验证更为严格的验证,以验证您具有:
仅寻找NUL字节是不够的。
话虽这么说,绝对不需要任何BOM字符来确定编码,也不需要MIME字符集-都不需要,而且JSONt_strong在JSON 中也不是必需的。
使用UTF-16和UTF-32时只需要使用二进制内容传输编码,因为它们可能包含NUL字节。 UTF-8没有这个问题,并且8位内容传输编码很好,因为它在字符串中不包含NUL(尽管它仍然包含> = 128的字节,所以7位传输将不起作用-存在UTF- 7可以用于这种传输,但是它不是有效的JSON,因为它不是唯一有效的JSON编码之一)。
有关更多详细信息,另请参见this answer。
回答您的后续问题
Are these correct deductions?
是。
Will I run into problem when implementing web-services or web-clients which adhere to this interpretations?
如果您与不正确的实现进行交互,则可能会发生。为了与不正确的实现实现互操作性,您的实现可能会忽略BOM。请参见RFC 7159, Section 1.8:
In the interests of interoperability, implementations that parse JSON texts MAY ignore the presence of a byte order mark rather than treating it as an error.
另外,忽略MIME字符集是兼容的JSON实现的预期行为-请参见RFC 7159, Section 11:
Note: No "charset" parameter is defined for this registration. Adding one really has no effect on compliant recipients.
安全注意事项
我个人并不认为始终需要静默接受不正确的JSON流。如果您决定接受带有BOM和/或MIME字符集的输入,则必须回答以下问题:
在三个独立的位置定义了编码-在JSON字符串本身,BOM和MIME字符集中,这不可避免地产生了问题:如果不同意该怎么办。除非您拒绝这样的输入,否则没有一个明显的答案。
例如,如果您有一个验证JSON字符串的代码,以查看是否可以安全地用JavaScript评估它-可能会被MIME字符集或BOM误导,并且将其视为与实际不同的编码,并且不会检测到字符串它会检测是否使用了正确的编码。 (过去类似的HTML问题导致XSS攻击。)
每当您决定接受带有多个且可能有冲突的编码指示符的不正确的JSON字符串时,就必须为所有这些可能性做好准备。并不是说您绝对不要这样做,因为您可能需要使用由错误的实现产生的输入。我只是说,您需要彻底考虑其含义。
不合格的实现
Should I file bugs against web browsers which violate the the two properties above?
当然-如果他们将其称为JSON,并且实现不符合JSON RFC,则这是一个错误,应这样报告。
您是否找到了任何不符合JSON规范的特定实现,但它们却宣传这样做呢?
关于json - JSON规范和BOM/字符集编码的用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4990095/