JSON 语法速查表 - JSON 数据格式常用命令大全
前后端联调时,JSON 是 API 响应的默认格式,也是最容易因末尾多逗号、键漏双引号而报错的格式之一。这份速查覆盖 6 组高频写法——数据类型、对象、数组、嵌套、常见 API 响应结构、校验与格式化命令(JSON.parse、jq 等):既帮你按模板写出规范数据,也提供排错对照与 jq 快速校验的入口。读完你能熟练拼装符合规范的 JSON,并快速用工具验证其正确性。
典型使用场景
前后端联调与接口对接时,JSON 是数据交换和返回的默认格式,最常见的场景有三种:拼装请求体、解析响应的嵌套字段,以及排查"为什么 JSON.parse 抛错"。比如接口返回 data.items 数组与 total 总数,你需要按 common patterns 的约定去读取分页字段;写请求体时则要严格保证键用双引号、无尾随逗号。拼好后用 jsonlint 或 jq 做一次校验,能大幅减少线上联调时因格式问题来回返工。读完本表,你能随手写出规范 JSON 并用工具自检正确性。
数据类型 Data Types 6
"string"123 / -456 / 3.14true / falsenull{"key": "value"}[1, 2, 3]对象 Object 5
{"name": "tom"}{"name": "tom", "age": 20}{"user": {"name": "tom"}}{"users": [{"name": "tom"}]}{"key with space": "value"}数组 Array 5
[1, 2, 3]["a", "b", "c"][{"id": 1}, {"id": 2}][[1, 2], [3, 4]][1, "text", true, null]嵌套结构 Nested 3
{"user": {"name": "tom", "age": 20}}{"users": [{"name": "tom"}, {"name": "jerry"}]}[{"id": 1, "tags": ["a", "b"]}]常见格式 Common Patterns 4
{"code": 200, "message": "success"}{"error": {"code": 404, "message": "Not found"}}{"data": {"items": [], "total": 100}}{"id": 1, "created_at": "2026-07-19T10:30:00Z"}校验与格式化 Validation 5
JSON.parse(str)JSON.stringify(obj)JSON.stringify(obj, null, 2)jsonlint file.jsonjq . file.json参数矩阵
| 参数 | 作用 | 示例 |
|---|---|---|
"string" | 字符串值,键与值都用双引号,是 JSON 里最常见的类型 | {"name": "tom"} |
123 / -456 / 3.14 | 数字,整数与浮点数不加引号;金额等精确值不能靠它承载 | {"age": 20} |
true / false | 布尔值,只能是小写形式,不接受 1 与 0 代替 | {"ok": true} |
null | 显式空值,与「键不存在」是两种不同状态,接口契约里要分清 | {"deleted_at": null} |
{"key": "value"} | 对象,键值对集合,同名键出现多次的结果由解析器决定 | {"key with space": "value"} |
[1, 2, 3] | 数组,有序列表且元素类型可以不同,下标访问从 0 开始 | ["a", "b", "c"] |
{ } | 对象里再放对象,用于表达有层级的结构,取值要逐层下钻 | {"user": {"name": "tom"}} |
[{ }] | 数组的每个元素是对象,接口返回列表时的标准形态 | {"users": [{"name": "tom"}, {"name": "jerry"}]} |
[[ ]] | 数组的元素仍是数组,适合直接映射成表格行列 | [[1, 2], [3, 4]] |
[mixed] | [1, "text", true, null] 这类数组解析没问题,但取值端必须先判类型 | [1, "text", true, null] |
{ code, message, data } | 业务码与提示文案放在响应体里,与 HTTP 状态码各管一层 | {"code": 200, "message": "success"} |
{ error: { code, message } } | 把错误信息收进 error 对象,让失败也有固定可解析的结构 | {"error": {"code": 404, "message": "Not found"}} |
{ items, total } | items 放当前页记录、total 放总数,两者分离便于前端算页数 | {"data": {"items": [], "total": 100}} |
"2026-01-01T00:00:00Z" | 统一写成带 Z 的 ISO 8601,避免各端各自格式化产生歧义 | {"id": 1, "created_at": "2026-07-19T10:30:00Z"} |
JSON.parse(str) | 把 JSON 字符串解析成对象,语法不合法时抛错而不是返回半成品 | |
JSON.stringify(obj) | 把对象转回 JSON 字符串,顺序键会被自动重排 | |
JSON.stringify(obj, null, 2) | 带 2 空格缩进的格式化输出,适合人读与版本 diff | |
jsonlint file.json | 命令行校验语法,把错误位置直接打到终端 | jsonlint file.json |
jq . file.json | 命令行美化与查询,同时兼作一次语法校验 | jq . file.json |
易错点与避坑指南
现象接口返回了数据,前端却判断为失败。
原因业务码写在响应体里(形如 {"code": 200, "message": "success"}),取值时直接读了布尔式判断,忽略了 code 这一层。
处置按分页或响应约定的路径取 code 再判定,不要依赖真假值猜测成功与否。
现象大整数 ID 传到后端变成了以 0 结尾的数字。
原因ID 写成 JSON 数字后超出双精度可精确表示的范围,解析时低位被抹平,雪花 ID 与超长订单号都会中招。
处置ID 一律用字符串传递,取值时也按字符串处理,不要在中间环节转成数字。
现象金额字段对不上账,差了极小的一截。
原因小数写成 JSON 数字后按二进制浮点存储,12.34 这类值本身就不存在精确表示,往返序列化后误差被保留下来。
处置金额改用整数最小单位或字符串传递,只在展示层再转成小数。
现象合并两个来源的对象后,某个字段凭空消失。
原因同名键在同一个对象里出现两次,不同解析器可能取后者覆盖前者,也可能取第一个,结果不一致且不报错。
处置合并后校验关键键唯一,必要时先给键加上来源前缀再合并。
现象本地看着正常的文件,在别的机器上解析就报非法转义。
原因路径里的反斜杠被当成转义序列的起始,反斜杠需要成对出现;Windows 分隔符直接拼进 JSON 就会踩这个坑。
处置序列化时交给 JSON.stringify 处理转义,不要手工拼接带路径的 JSON 字符串。
现象接口里的中文变成了问号或方块,emoji 直接丢失。
原因传输或文件读取时未按 UTF-8 处理,被按单字节编码解读,字节序列错位后无法还原。
处置读写两端都显式声明 UTF-8,Content-Type 里补上 charset 参数。
现象解析能过,但取到的层级是 undefined。
原因对象数组这一层容易少写一层下标,例如 {"users": [{"name": "tom"}]} 取值时要先落到 users 再落到每个元素。
处置先用 jq . file.json 把结构打印出来核对层级,再写取值路径。
现象解析报错但看不出错在哪一行。
原因报错信息常只给字符位置不给原因,而真正的问题往往是尾随逗号、注释或没加引号的键这类局部错误。
处置用 jsonlint file.json 单独校验一遍,把定位出的位置与附近文本对照检查。
现象同一份数据在不同端解析出的键顺序不一致,diff 全是噪音。
原因对象是无序的,序列化时键会被重排,顺序本身不携带语义却污染了版本差异。
处置比较结构而不是比较文本,先用 jq . file.json 规范化两边再比对。
排障路径
1先做一次语法校验,把错误位置钉死
jsonlint file.json无输出即语法通过;有输出时输出的位置就是第一处错误所在,优先修这一处再重跑。
2把文件美化打印出来核对结构层级
jq . file.json合法文件会被重新缩进打印;非法文件会在此处直接报错,等于顺带做了校验。
3取出分页结构里的总数字段确认取到了值
jq '.data.total' file.json对应 {"data": {"items": [], "total": 100}} 这一形状;输出 null 说明层级与实际结构不一致,需要先看结构再改路径。
4用 Node 复现解析失败,拿到带位置的报错
node -e 'JSON.parse(require("fs").readFileSync("file.json","utf8"));console.log("ok")'打印 ok 说明解析通过;抛错时错误对象里带字符位置,比只看到一句语法错误更好定位。
5确认格式化输出确实带上了缩进
node -e 'const o={user:{name:"tom",age:20}};console.log(JSON.stringify(o,null,2))'缩进两格的输出用于人读与 diff;若仍是一整行,说明第二个参数传的位置不对。
命令示例
格式化输出便于人读与 diff 对比
JSON.stringify(obj, null, 2)压缩后的单行 JSON 一旦改动就整行变红,review 时完全看不出差异。用 2 空格缩进输出(JSON.stringify 的第三参数)后,改一个字段只对应一行 diff。
输出
{
"name": "tom",
"tags": [
"a",
"b"
]
}用 jq 取出需要的字段并校验结构
jq '[.users[] | {id, name}]' data.json.users[] 展开数组并逐元素投影字段,输出体积大幅缩小。jq 在字段缺失时会输出 null 而不是报错,适合用来快速确认接口返回的嵌套层级是否与预期一致。
输出
[
{
"id": 1,
"name": "tom"
},
{
"id": 2,
"name": "jerry"
}
]提交前用 jsonlint 卡住语法错误
jsonlint data.json尾随逗号、单引号、未转义的换行都是肉眼难发现的错误,解析时只报一个笼统的「Unexpected token」,定位成本高。入库或提交前先 jsonlint,能省掉整轮排查。
输出
data.json: Invalid JSON:
1:14: trailing comma
$ jsonlint data.json
Error: Invalid JSON
line 1 column 14
trailing comma时间戳一律写成带 Z 的 RFC 3339
{ "id": 1, "created_at": "2026-07-19T10:30:00Z" }不带 Z 的时间串在不同客户端会被按本地时区解读,日界与账单就对不上。带 Z 或 +08:00 偏移量的写法让解析结果唯一,跨时区聚合也不会错。
常见坑与注意事项
- JSON 不支持注释也不支持尾随逗号:配置文件里顺手加 // 说明或最后一项后留逗号,会让解析器直接失败,而很多语言的 JSON 解析报错只给位置不给原因。
"a\b"这类非法转义序列会让严格解析器报错:反斜杠必须写成\\,路径里的 Windows 分隔符直接放进 JSON 会踩这个坑。- JSON 数字是双精度浮点,金额用 12.34 存储会因二进制表示误差变成 12.339999999999999;涉及钱的字段一律用整数最小单位或字符串传递。
- 键名重复时不同解析器行为不一致(后者覆盖前者、有的取第一个),对象由多个来源合并时容易静默丢字段,合并后应校验关键键唯一。
- 大整数超过 2^53 会被精度截断,ID 用 JSON number 传输时前 16 位之后可能全变 0;雪花 ID、超长订单号应按字符串传递。
- 字符串里的中文与 emoji 在未声明 UTF-8、按 Latin-1 解析时会变成乱码,且乱码数据一旦入库就很难追回原始内容。
提示
- JSON 键名必须用双引号,不能用单引号或不加引号。
- JSON 不支持注释,如果需要注释用 JSONC(JSON with Comments)。
- 日期时间建议用 ISO 8601 格式(如 "2026-07-19T10:30:00Z")。
常见问题
json 字符串值里有换行该怎么写?
JSON 不允许字符串里出现真实的换行符,必须转义成 \n;同理制表符用 \t。用 JSON.stringify(value) 会自动完成转义,比手写更不易出错。中文则可以不转义,按 UTF-8 直接写即可,多数解析器都能正常读取。
json 报错一般是哪些原因,怎么快速定位?
最常见三类:漏了键名双引号、对象或数组最后多了一个逗号(trailing comma)、括号与引号不成对。用 jq . 校验会提示所在行和错误类型;前端把 JSON.parse 包进 try/catch 并打印出错片段,逐步二分注释缩小范围。
json 里的中文需要转义吗?
按规范并不强制,UTF-8 下直接写中文是合法 JSON,大多数解析器都能正常读。只有协议要求 ASCII-only(如某些旧的头或日志管道)时,才需把中文转成 \uXXXX 形式,可用工具的 -ascii 选项或 JSON.stringify 的替代实现统一处理。
json 数字写成带引号的字符串有问题吗?
语法上没问题但语义不同:"123" 是字符串,123 是数字,前端 typeof 与运算结果都不同,排序也会变字典序。需要保留前导零或超长 ID 时用字符串;其余数值应写成数字字面量,布尔值用 true/false 而不要写成字符串。
json 含嵌套或大文件怎么快速校验和取值?
用 jq 最方便:jq . file.json 校验并美化,jq '.key' 取值,jq 'length' 看数组长度;只想检查是否合法可 jq empty file.json。前端用 JSON.parse 包 try/catch 校验,可视化可用 jqplay 或在线 JSON 验证器。
由 巧匠 维护
公开更新于 2026年7月21日,内容持续校对官方文档。