当前位置: 首页 > 面试题库 >

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

昌山
2023-03-14
问题内容

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

在将有效载荷宣传为application/json哑剧类型时,

  1. 必须 是没有BOM在正确编码JSON的开始小号流(基于部分“3.编码”),以及
  2. 没有媒体参数也被支持,从而一个的mime类型报头application/json; charset=utf-8 符合RFC-4627(基于部分“6. IANA考虑”)。

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


问题答案:

你是对的

  1. BOM字符在JSON中是非法的 (不需要)
  2. MIME字符集在JSON中是非法的 (也不需要)

RFC 7159第8.1节:

实现不得在JSON文本的开头添加字节顺序标记。

尽可能清楚地说明这一点。这是整个RFC中唯一的“不得”。

RFC 7159第11节:

JSON文本的MIME媒体类型为application / json。
类型名称:application
子类型名称:json
必需参数:不适用
可选参数:不适用
[…]
注意: 此注册未定义“字符集”参数。


JSON编码

JSON的唯一有效编码是UTF-8,UTF-16或UTF-32,并且由于第一个字符(如果有多个字符,则为前两个字符)将始终具有小于128的Unicode值(没有有效的JSON)可以包含前两个字符的较高值的文本),始终可以通过查看字节流来知道使用哪种有效编码以及使用哪种字节序。

RFC建议

JSON RFC表示前两个字符将始终在128以下,并且您应检查前4个字节。

我用不同的说法:由于字符串“ 1”也是有效的JSON,因此不能保证您有两个字符-更不用说4个字节了。

我的建议

我对确定JSON编码的建议会稍有不同:

快速方法:

  1. 如果您有1个字节且不是NUL,则为 UTF-8
    (实际上,这里唯一有效的字符是ASCII数字)

  2. 如果你有2个字节,他们都不是NUL -它的 UTF-8
    (那些必须为ASCII数字,没有领先的“0”, {}[]""

  3. 如果您有2个字节,而只有第一个为NUL,则为 UTF-16BE
    (必须为ASCII数字,编码为UTF-16,大端)

  4. 如果您有2个字节,而第二个字节是NUL,则为 UTF-16LE
    (必须为ASCII数字,编码为UTF-16,小端)

  5. 如果您有3个字节,但它们不是NUL,则为 UTF-8
    (同样,不带前导0的ASCII数字"x"[1]等等)

  6. 如果您有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所包含的验证更严格的验证,以验证您具有:

  1. UTF-8,UTF-16或UTF-32的有效编码(LE或BE)
  2. 有效的JSON

仅寻找NUL字节是不够的。

话虽 这么 说, 您根本不需要任何BOM字符来确定编码,也不需要MIME字符集 - 不需要 这两个 字符 ,并且
在JSON中均无效

使用UTF-16和UTF-32时只需要使用二进制内容传输编码,因为它们可能包含NUL字节。UTF-8没有这个问题,并且8位内容传输编码很好,因为它在字符串中不包含NUL(尽管它仍然包含>
= 128的字节,所以7位传输将不起作用-存在UTF- 7可以用于这种传输,但是它不是有效的JSON,因为它不是唯一有效的JSON编码之一)。

回答您的后续问题

这些是正确的推论吗?

是。

在实施遵循这种解释的Web服务或Web客户端时,我会遇到问题吗?

如果您与错误的实现进行交互,则可能会发生。为了与不正确的实现实现互操作性,您的实现可以忽略BOM-参见RFC
7159第1.8节:

为了互操作性,解析JSON文本的实现可以忽略字节顺序标记的存在,而不是将其视为错误。

同样,忽略MIME字符集是兼容JSON实现的预期行为-请参阅RFC
7159,第11节:

注意:没有为该注册定义“字符集”参数。确实添加一个对符合条件的收件人没有任何影响。

安全注意事项

我个人并不认为始终需要静默接受不正确的JSON流。如果您决定接受带有BOM和/或MIME字符集的输入,则必须回答以下问题:

  • 如果MIME字符集和实际编码不匹配该怎么办?
  • 如果BOM和MIME字符集不匹配怎么办?
  • 如果BOM与实际编码不匹配怎么办?
  • 当所有人都不相同时该怎么办?
  • 使用UTF-8 / 16/32以外的编码怎么办?
  • 您确定所有安全检查都能按预期进行吗?

在三个独立的位置定义编码-
在JSON字符串本身,BOM和MIME字符集中,这不可避免地产生了问题:如果不同意该怎么办。除非您拒绝这样的输入,否则没有一个明显的答案。

例如,如果您有一个验证JSON字符串的代码,以查看是否可以安全地用JavaScript评估它-
可能会被MIME字符集或BOM误导,并且将其视为与实际不同的编码,并且不会检测到字符串它会检测是否使用了正确的编码。(HTML的类似问题过去也导致XSS攻击。)

每当您决定接受带有多个且可能有冲突的编码指示符的不正确的JSON字符串时,就必须为所有这些可能性做好准备。并不是说您绝对不要这样做,因为您可能需要使用错误的实现所产生的输入。我只是说,您需要彻底考虑其含义。

不合格的实施

是否应该针对违反上述两个属性的Web浏览器提交错误?

当然-如果他们将其称为JSON,并且实现不符合JSON RFC,则这是一个错误,应这样报告。

您是否找到了任何不符合JSON规范的特定实现,但它们却宣传这样做呢?



 类似资料:
  • 这个编码规范是给TypeScript开发团队在开发TypeScript时使用的。 对于使用TypeScript的普通用户来说不一定适用,但是可以做为一个参考。 命名 使用PascalCase为类型命名。 不要使用I做为接口名前缀。 使用PascalCase为枚举值命名。 使用camelCase为函数命名。 使用camelCase为属性或本地变量命名。 不要为私有属性名添加_前缀。 尽可能使用完整的

  • 以下是 Electron 项目的编码规范,您可以运行 npm run lint来显示 cpplint和 eslint检测到的任何规范问题 C++ 和 Python 对于C ++和Python,我们遵循Chromium的编码风格. 您可以使用clang-format自动格式化C ++代码.也可以使用 script/cpplint.py 来检验文件是否符合要求. 我们目前使用的 Python 版本是

  • CakePHP 开发人员将使用下面的编码规范。 我们建议其他开发Cake组成部分的人员也应当遵循同样的规范。 你可以使用 CakePHP Code Sniffer 来检查你 的代码是否遵循了必要的规范。 添加新特性 添加新特性,必须伴随相应的测试用例,在提交到代码仓库前,测试用例必须通过。 缩进 缩进使用一个制表符。 所以,缩进应当看起来象这样: // 底层 // 第1层

  • There are many languages in use throughout the world, and they use many different character sets. There are also many ways of encoding character sets into binary formats of bytes. This chapter conside

  • 问题内容: 我有一些json,我需要解码,更改然后编码,而不会弄乱任何字符。 如果我在json字符串中包含unicode字符,它将无法解码。我不知道为什么,因为json.org说一个字符串可以包含:。但这在python中也不起作用。 我可以使用utf8_encode,该字符串将允许使用json_decode对字符串进行解码,但是字符会被压缩成其他形式。这是来自结果数组的print_r的结果。两个字

  • 问题内容: 我从一个包含特殊字符的国外来源中检索了基于文本的utf8数据,例如,当我想将它们标准化为英语时,例如。实现这一目标的最佳方法是什么? 问题答案: 我建议使用Unidecode模块: 请注意如何为它提供一个unicode字符串,并输出一个字节字符串。保证输出为ASCII。