开发者工具 · JSON 格式化程序和验证程序
整个 JSON 语法在一页上:六个值类型,两个容器
· 背景
json 标准 验证
JSON 的整个语法都在一页上,并且熟记它使得每个验证器错误都显而易见。这篇文章将介绍六种值类型、两种容器以及一些令人困惑的规则。
您见过的每个错误都来自一页
每个语法错误都是紧凑语法中的破坏期望。打开对象后,解析器需要带引号的成员名称或右大括号;在名称之后,需要一个冒号;在一个值之后,它需要一个逗号或容器的结尾。将错误视为失败的转换比将报告的字符视为神秘的字符更有用。
ToolAcre 接受标准 JSON 值和空格,然后应用两个实际输入限制。解析之前,长度超过 8,000,000 个字符的文本将被拒绝,超出 512 容器的扫描器嵌套将被拒绝,而不是无限期地遍历。这些是产品边界,而不是新的 JSON 类型。在其中,诊断识别出令牌流不再满足语法的第一个点。
六个值 — 对象、数组、字符串、数字、true/false 和 null,事实上没有其他值
JSON 值是对象、数组、字符串、数字、布尔值或 null。对象和数组可以包含这六个容器中的任何一个,包括更多容器。字面拼写完全是 `true`、`false` 和 `null`;大小写不灵活。诸如 `True`、`None`、`undefined`、`NaN` 和 `Infinity` 之类的标记位于严格的 JSON 之外,即使另一种语言可以识别其中的某些标记。
这个简短的列表使分类成为一种有用的调试技术。在 `{"reading": NaN}` 中,冒号正确引入了一个值,但 `N` 不能开始任何允许的值。仅在确定数据的含义后才替换它,可能是 `null` 或引用的状态。语法工具可以拒绝该标记;它无法选择应用程序的替代品或决定该字段是否属于那里。
对象和数组 — 逗号分隔的成员、冒号以及为什么 RFC 8259 将排序和重复名称留给实现
对象包含逗号分隔的名称 /value 成员。每个名称都是一个双引号字符串,后跟一个冒号和一个值。数组包含逗号分隔的值,没有名称或冒号。空 `{}` 和 `[]` 容器有效,但逗号不能开头、结尾或出现两次。将每个分隔符与其容器相匹配会很快暴露出许多明显的“意外令牌”故障。
对象名称应是唯一的,但此验证器不会拒绝重复的拼写。 `{"port": 80, "port": 443}` 解析,`JSON.parse` 保留后面的值。然后,格式化仅发出幸存的成员,因此无法从结果中恢复较早的文本。数组位置的行为有所不同:每个元素仍然存在,并且其顺序是值的一部分。
精确的字符串和数字
字符串使用双引号。反斜杠可以引入引号、反斜杠、斜杠、`b`、`f`、`n`、`r`、`t` 或四位 Unicode 转义;禁止使用原始控制字符。单引号是字符串外部的普通无效标记。这些规则解释了为什么复制的 JavaScript 文字和粘贴的多行文本看起来可读,但未通过严格的 JSON 验证。
数字可以有减号、整数部分、可选分数和可选指数。它不能以 `+` 开头、使用十六进制表示法、在另一个数字之前带有前导零或拼写非有限值。 `-0.25e+2` 有效; `01`、`.5`、`2.` 和 `Infinity` 不是。解析检查语法,而不检查 JavaScript 是否可以准确保留每个数字。
空白和顶层
在字符串之外,JSON 空白仅限于空格、水平制表符、换行符和回车符。从网页复制的不间断空格不能与普通空格互换。格式化可以在标记周围自由选择允许的空格,但它必须保留属于带引号的字符串内的空格,因为这些字符是数据。
完整文档可以是任何单个 JSON 值,而不仅仅是对象或数组。 `42`、`false` 和 `"ready"` 是有效的顶级文本。禁止的是第一个值之后的第二个值: `42 43` 是两个文档,而不是一个。这种区别解释了为什么换行符分隔的 JSON 需要逐条记录处理,而不是对整个文件进行普通解析。
工作示例:手动解析小文档
采用 `{"order": [17, null, {"paid": true}], "note": "ship soon"}`。根对象开始一个名为 `order` 的成员;它的值是一个包含数字、null 和另一个对象的数组。然后逗号引入 `note`,其值是带有转义换行符的字符串。每个冒号、逗号和结束定界符都有一个语法作用。
现在删除 `paid` 之前的引号。在嵌套大括号之后,解析器需要一个右大括号或带引号的名称,因此它在 `p` 处失败。或者,在 `true` 之后添加逗号;解析器接受逗号,然后在 `}` 处失败,因为后面必须有另一个成员。手动预测这些位置可以将验证转变为确认,并阻止随机标点符号编辑。
这不包括什么
语法没有日期、十进制货币、二进制、UUID 或持续时间类型。应用程序通常用字符串或数字来表示这些概念,并分别施加约定。时间戳可以是完全有效的 JSON 字符串,但包含不可能的日期。同样,语法上有效的对象可以省略所需的属性或使用错误的单位,而不会违反单个解析规则。
ToolAcre 不执行架构检查、域验证或规范化。它也不会重新解释 JSON5 或 JSONC 功能,例如注释和尾随逗号。它的工作范围更窄:接受产品限制内的一个严格的 JSON 文本,格式化解析的值,并识别语法错误。将有关形状和含义的后续问题保留在消费应用程序的验证层中。
要点:记住语法,相信位置
持久清单很短:六个值类别、带引号的对象名称、仅在项目之间使用逗号、仅在名称和值之间使用冒号、严格的字符串转义、严格的数字拼写、四个空白字符以及一个顶级值。当文档失败时,确定报告位置之前允许的语法,并将该期望与实际存在的字符进行比较。
相信该位置是第一个不可能点,而不总是需要删除的字符。右大括号可能会突出显示,因为前面的逗号承诺了另一个成员;一封无辜的信件可能会因为缺少开头引文而被突出显示。修复原因,重新运行验证,然后重复。对于超大或极深的输入,请先解决 8 百万字符或 512 深度的产品边界,然后语法诊断才能提供帮助。