首页 / 博客 / 详情

JSON 语法

作者:sa | 2026-11-05 | 浏览 2 JSON

JSON 的语法规则其实只有一页纸,但线上接口的解析报错,绝大多数都出自这页纸上的细节:键名忘了加双引号、末尾多了一个逗号、数字带了前导零、文件开头混进了 BOM。本文把 JSON 的语法拆成结构、类型、字符三个层面逐条讲清,再给出可直接对照的错误清单,帮助你从“能看懂”走到“能写对、能排错”。

一、JSON 的语法结构

RFC 8259 对 JSON 的定义非常克制:一段 JSON 文本就是一个“值”(value)。值只有两种复合形态——对象和数组,其余都是标量。可以把它抽象成下面这棵树:

value
├── object   { "key": value, ... }
├── array    [ value, ... ]
├── string   "text"
├── number   123 / -4.5 / 1e3
├── boolean  true / false
└── null     null

由此可以推出三条最基本的语法约束:

  1. 顶层只能有一个值:要么是一个对象,要么是一个数组,不能是两段并列的内容,也不能是裸的键值对。
  2. 复合结构必须闭合:{ 与 }、[ 与 ] 必须成对,且不能交叉嵌套。
  3. 分隔符只用英文符号:冒号 : 分隔键和值,逗号 , 分隔成员,全部是半角字符。

二、对象:键必须是被双引号包裹的字符串

对象是无序的键值对集合,写法为 { "key": value }。这里有一个新手最容易忽略的点:键名必须是双引号字符串,不能是单引号,也不能是裸标识符。

// 合法
{ "name": "zjson", "version": 2 }

// 非法:键没有引号
{ name: "zjson" }

// 非法:键用了单引号
{ 'name': 'zjson' }

另外几条容易踩的规则:

  • 键与值之间必须有冒号,冒号两侧的空白可有可无。
  • 成员之间用逗号分隔,最后一个成员后面不能有逗号。
  • 同一个对象内不建议出现重复键。规范没有强制禁止,但不同解析器的处理方式不一致(有的保留最后一个,有的保留第一个),会给排查带来麻烦。
  • 对象不能直接作为另一个对象的键,键只能是字符串。

三、数组:有序的值列表

数组用方括号包裹,元素之间用逗号分隔,元素可以是任意 JSON 值,类型允许混合:

[1, "two", true, null, { "id": 3 }, [4, 5]]

数组同样不允许尾逗号,也不允许空槽位(如 [1,,3])。空数组写作 [],空对象写作 {},两者都是合法的。

实际接口中常见两种顶层结构:单个资源用对象,批量数据用数组。[{"id":1},{"id":2}] 是合法的顶层 JSON,解析后就是一个长度为 2 的列表。

四、六种数据类型与严格写法

类型合法示例关键规则
字符串"zjson"必须双引号,内部双引号与反斜杠需转义
数值0、-12、4.5、1e3不区分整数与浮点,禁止前导零、NaN、Infinity
布尔true、false只能小写,不能写成 True/False
空值null只能小写,表示“无值”,不等于 0 或空串
对象{"a":1}键必须是双引号字符串,成员间用逗号
数组[1,2,3]有序,元素类型可混合,禁止尾逗号

4.1 数字的写法

JSON 数字的语法比 JavaScript 严格,下面这些写法都会导致解析失败:

01        // 非法:前导零
+1        // 非法:不允许正号
.5        // 非法:小数点前必须有数字
5.        // 非法:小数点后必须有数字
0x1F      // 非法:不支持十六进制
NaN       // 非法:非数字
Infinity  // 非法:无穷大

正确的写法是 1、-1、0.5、5.0、1e3、1E-3。需要注意精度问题:超过 2^53-1 的整数(如订单号、雪花 ID)在 JavaScript 中会丢失精度,建议在接口里直接以字符串形式返回。

4.2 字符串与转义字符

字符串必须使用双引号。内部需要出现的双引号、反斜杠、换行等字符,必须使用转义序列:

转义含义示例
\"双引号"say \"hi\""
\\反斜杠"C:\\temp\\a.txt"
\/正斜杠(可选)"a\/b"
\b退格"a\bb"
\f换页"a\fb"
\n换行"line1\nline2"
\r回车"a\rb"
\t制表符"a\tb"
\uXXXXUnicode 码点"\u4f60\u597d" 即“你好”

标准 JSON 不允许使用单引号字符串,也不支持多行字符串。中文、日文、Emoji 建议直接写 UTF-8 字符,只有在链路强制 ASCII 时才需要转成 \uXXXX。

五、空白、编码与注释

空白字符(空格、制表符、换行、回车)可以出现在任意两个语法记号之间,用于美化排版,但不影响数据本身。因此下面两种写法在解析后完全等价:

{"a":1,"b":2}

{
  "a": 1,
  "b": 2
}

空白只能出现在记号之间。如果把它塞进键名或数字内部,例如 {"na me": 1} 是合法的(空格属于键名的一部分),而 {"a": 1 2} 则会直接报错。

编码方面:

  • JSON 文本推荐使用 UTF-8,传输时声明 Content-Type: application/json; charset=utf-8。
  • 文件保存为 UTF-8 无 BOM。BOM 头对 JSON 解析器是非法字符,常表现为“第一行第一列报错”,肉眼却看不到异常。
  • 文言文件里的全角引号、全角逗号、全角冒号都属于非法字符,粘贴时尤其容易混入。
  • 标准 JSON 不支持任何注释。需要说明信息时,只能新增字段(如 "_comment"),或改用 JSON5 / JSONC 等扩展格式。

六、一个覆盖全部语法的完整示例

{
  "id": 1001,
  "name": "zjson",
  "verified": true,
  "score": 4.9,
  "balance": null,
  "tags": ["json", "syntax", "api"],
  "contact": {
    "city": "杭州",
    "phone": "13800000000"
  },
  "orders": [
    { "sku": "P-100", "qty": 2, "price": 99.5 },
    { "sku": "P-200", "qty": 1, "price": 100.0 }
  ]
}

这段文本包含了对象、数组、字符串、数值、布尔和 null 六种类型,也包含了两层嵌套。校验时可以重点检查:所有键是否有双引号、每层是否闭合、最后一个成员后面是否多了逗号。

七、高频语法错误对照表

错误写法错误原因正确写法
{name:"a"}键名缺少双引号{"name":"a"}
{'name':'a'}使用了单引号{"name":"a"}
{"a":1,}多余的尾逗号{"a":1}
[1,2,]数组尾逗号[1,2]
{"a":01}数字前导零{"a":1}
{"a":NaN}非法数值{"a":null} 或字符串
{"a":undefined}非 JSON 值{"a":null}
{"a":1} {"b":2}顶层出现多个值合并为一个对象或改为数组
// 注释标准 JSON 不支持注释删除注释或改用 JSONC
文件带 BOM / 全角标点隐藏字符与非法字符转 UTF-8 无 BOM,替换为半角符号

八、怎么快速定位语法错误

遇到解析失败时,可以按下面的顺序排查:

  1. 先格式化:把整段文本交给格式化工具,结构错乱、括号不匹配会立刻暴露。
  2. 看报错行列号:多数解析器会给出出错位置。注意报错位置有时指向问题字符的下一个记号,需要往前看一两个字符。
  3. 检查隐藏字符:重点看文件开头是否有 BOM、是否混入全角标点、是否有从网页复制来的不可见字符。
  4. 缩小范围:删掉一半内容再校验,用二分法快速锁定出错片段。

手工排查效率低时,直接使用在线工具会更快:JSON 在线格式化 可以在美化同时标出语法错误位置,JSON 校验工具 用于确认文本是否合法,JSON 压缩 则适合在确认无误后减小体积。若需要比对两份配置的差异,可用 JSON 对比工具。

九、JSON 与 JSON5:什么时候可以“放宽语法”

因为标准 JSON 太严格,工程里出现了 JSON5、JSONC 等扩展格式,它们允许单引号、注释、尾逗号、裸键名等写法。典型场景是编辑器配置文件(如 VS Code 的 settings.json 允许注释)。但需要注意:

  • 对外提供的接口、跨语言传输的数据,必须使用标准 JSON。
  • 扩展格式只能保证被特定工具解析,换一个解析器就可能失败。
  • 如果配置里必须写注释,优先确认目标解析器是否支持 JSONC,而不是默认所有环境都支持。

十、小结

JSON 语法可以用三句话记住:顶层一个值、键名双引号、末尾无逗号。再叠加数字与字符串的严格写法、UTF-8 无 BOM 编码,就能覆盖日常开发中绝大多数语法问题。写完 JSON 后先过一遍格式化或校验工具,比在代码里调试解析异常省事得多。

上一篇
JSON 是什么
下一篇
没有了