写接口的时候,JSON 解析失败是最让人烦躁的问题之一。报错信息通常只有一句 Unexpected token,不告诉你错在哪。更麻烦的是,很多编辑器根本不会在保存 JSON 时指出语法错误,等你发现的时候往往已经改了很多行。
这篇讲清楚最常踩的五个坑,以及怎么快速定位。
错误一:尾随逗号(最常见)
JSON 规范不允许对象或数组的最后一个元素后面带逗号。这是 JavaScript 和 JSON 最大的区别之一,因为 JavaScript 允许尾随逗号。
{
"name": "toolnest",
"tags": ["free", "fast"], // 这个逗号在 JSON 里是错的
}
报错:
Unexpected token } in JSON at position 42
改法:删掉 ] 或 } 前面那个逗号。
为什么会踩:很多人是从 JavaScript 对象里复制一段过来,因为 JS 允许尾随逗号,格式化工具也不报错——直到发到服务器。
错误二:单引号
JSON 强制要求双引号。单引号在 JavaScript 里合法,在 JSON 里不合法。
{
'name': 'toolnest' // 错误
}
如果你习惯用单引号,或者从某个配置文件里复制过来,很容易中招。可以在编辑器里全局替换,或者用格式化工具——它会直接告诉你哪一行出错。
错误三:字符串里没有转义的换行
JSON 字符串不能包含字面的换行符。要换行必须写成 \n。
{
"description": "第一行
第二行" // 错误
}
正确写法:
{
"description": "第一行\n第二行"
}
这个错误特别隐蔽,因为很多编辑器会显示成两行,但文件里其实是一个换行符。报错通常是 Bad control character in string literal。
错误四:注释
JSON 规范里没有注释。但很多人会习惯性写上,因为 JavaScript、Python、TypeScript 都支持。
{
// 这是注释
"name": "toolnest"
}
报错 Unexpected token /。
注意:某些服务端框架(比如用 JSON5 或 jsonc 解析的)确实接受注释,但标准的 JSON.parse() 不接受。从本地配置文件里读出来发给后端时,这个差异就会咬人。
错误五:数字格式不对
JSON 的数字格式比 JavaScript 严格:
| 写法 | 是否合法 | 说明 |
|---|---|---|
123 | ✅ | 整数 |
1.5 | ✅ | 小数 |
-0.5 | ✅ | 负数 |
1e10 | ✅ | 科学计数法 |
01 | ❌ | 不能有前导零 |
+1 | ❌ | 不能有正号 |
.5 | ❌ | 小数点前必须有数字 |
1. | ❌ | 小数点后必须有数字 |
NaN | ❌ | 不是合法 JSON |
Infinity | ❌ | 不是合法 JSON |
NaN 和 Infinity 尤其要注意。JavaScript 里 JSON.stringify 会把它们转成 null,但你手动构造字符串时很容易直接写上去。
怎么快速定位
手动数字符位置是最笨的办法。更好的做法:
1. 用格式化工具直接看行号列号
把有问题的 JSON 粘进 JSON 格式化工具,它会报出精确的行和列:
JSON 无效(行 4,列 12)
…{
"name": "toolnest",
"tags": ["free", "fast"],
}…
2. 二分法
如果文件很大,先删掉一半再试,定位到大致范围后继续缩小。
3. 检查最可疑的几处
按经验,出现频率从高到低是:尾随逗号 → 单引号 → 注释 → 字符串里的换行。
4. 用编辑器的 JSON 插件
VS Code 默认就带 JSON 语法检查,保存时会直接标红,比运行时才发现强太多。
顺便说说格式化本身
格式化的价值不只是好看:
- 便于 diff:格式化后每行一个字段,改动一目了然
- 便于排查:缩进和换行会暴露嵌套层级,肉眼就能看出括号配对
- 便于压缩:生产环境传输前可以压缩掉所有空白,通常能省 10–30% 体积
JSON 格式化工具 支持 2 空格、4 空格、Tab 和压缩四种输出,全部在浏览器本地运行,不上传任何内容。