json - JSON规范和BOM/字符集编码的用法

标签 json mime-types rfc

我一直在阅读RFC-4627规范,并开始进行解释:

在将有效载荷发布为application/json mime-type时,

  • 在正确编码的JSON流(基于“3.编码”一节)的开头,必须为,不得为BOM,而
  • 不支持任何媒体参数,因此application/json; charset=utf-8的mime类型 header 而不是符合RFC-4627(基于“6. IANA注意事项”部分)。

  • 这些是正确的推论吗?在实现遵循此解释的Web服务或Web客户端时,我会遇到问题吗?是否应该针对违反上述两个属性的Web浏览器提交错误?

    最佳答案

    你是对的

  • BOM字符在JSON中是非法的(并且不需要)
  • MIME字符集在JSON中是非法的(并且也不需要)

  • 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编码的建议会稍有不同:

    快速方法:
  • (如果您有1个字节,并且不是NUL)-,即 UTF-8
    (实际上,这里唯一有效的字符是ASCII数字)
  • (如果您有2个字节,但都不是NUL)-,即 UTF-8
    (必须是不带前导“0”,{}[]""的ASCII数字)
  • (如果您有2个字节,只有第一个是NUL)-,即 UTF-16BE
    (必须是编码为UTF-16,大端的ASCII数字)
  • (如果您有2个字节,只有第二个字节为NUL)-,即 UTF-16LE
    (必须为ASCII数字,编码为UTF-16,小端)
  • (如果您有3个字节,但它们不为NUL)-为utf-8
    (同样,不带前导0的ASCII数字,"x"[1]等。)
  • (如果您有4个字节或更多个字节,而不是RFC方法有效):
  • 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所包含的验证更为严格的验证,以验证您具有:
  • UTF-8,UTF-16或UTF-32(LE或BE)的有效编码
  • 有效的JSON

  • 仅寻找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字符集的输入,则必须回答以下问题:
  • 如果MIME字符集和实际编码不匹配怎么办?
  • 如果BOM和MIME字符集不匹配怎么办?
  • 如果BOM与实际编码不匹配怎么办?
  • 当它们都不同时该怎么办?
  • 如何处理UTF-8 / 16/32以外的编码?
  • 您确定所有安全检查都会按预期进行吗?

  • 在三个独立的位置定义了编码-在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/

    相关文章:

    url - 有没有一种半标准的方法可以将 URL 与 IRC 用户相关联?

    windows - 在 Windows XP 中基于每个套接字启用 RFC1323?

    ios - RestKit 响应未正确映射

    python - 如何以 "\r\n"结尾 JSON 文件?

    php - 产品未显示在电子商务网站上

    javascript - 使用 MIME 类型 application/json 可能会导致什么问题?

    android - 防止将自定义 mimetype 拖放到 EditText

    asp.net-mvc - Asp.Net MVC2 RenderAction 更改页面 mime 类型?

    https - 有 HTTPS 标准吗?

    javascript - 使用 jQuery 拉取 JSON 对象以避免 XSS