JSON 解析错误排查:Unexpected token、尾逗号、引号和大整数
JSON.parse() 很严格。严格是数据交换的优点,但也意味着 JavaScript 对象字面量、日志里的“类 JSON”、和真正合法 JSON 之间的小差异,都会导致解析失败。
最常见的 JSON 解析错误来自:
- 尾逗号
- 单引号
- key 没有双引号
- 注释
- 复制了日志前缀
- 字符串转义错误
- 接口返回的是 HTML 或纯文本,不是 JSON
- 大整数解析后丢失精度
JSON 不是 JavaScript 对象字面量
下面是合法 JavaScript,但不是合法 JSON:
{
name: 'Ada',
active: true,
}
合法 JSON 必须使用双引号包住 key 和字符串,并且不能有尾逗号:
{
"name": "Ada",
"active": true
}
如果浏览器控制台、文档或后端日志里展示的“JSON”带单引号或未加引号的 key,在严格解析前都应该当作类 JSON 文本。
常见 Unexpected token 原因
Unexpected token 表示解析器在某个位置遇到了不该出现的字符。
{"name": "Ada",}
"Ada" 后面的尾逗号非法。
{'name': 'Ada'}
单引号非法。
{name: "Ada"}
对象 key 必须使用双引号。
{
"name": "Ada" // user name
}
JSON 里不能有注释。
先确认响应真的是 JSON
API 调用出现 JSON parse error 时,先看原始响应,不要先改解析代码。
常见意外情况:
- 服务端返回了 HTML 错误页
- 代理返回了登录页
- 接口返回
204 No Content,body 为空 - 后端在 JSON 前输出了 warning
- 响应被压缩或编码方式异常
前端可以临时这样调试:
const text = await response.text()
console.log(text)
const data = JSON.parse(text)
如果第一个字符是 <,你很可能在解析 HTML。如果开头是 Warning: 或堆栈信息,应先修服务端输出。
先验证,再格式化
格式化工具能让合法 JSON 更易读,但不能在没有假设的情况下安全格式化非法 JSON。
用 JSON 工具定位:
- 第一个非法字符
- 错误行列
- 括号是否匹配
- 字符串转义是否正确
- 属性之间是否缺逗号
然后修源数据。不要依赖格式化工具自动“修复”生产 payload,除非你清楚它改了什么。
正确处理转义字符
JSON 字符串里,反斜杠是转义字符。
合法:
{
"path": "C:\\\\Users\\\\Ada",
"quote": "She said \\\"hello\\\""
}
非法:
{
"path": "C:\Users\Ada"
}
如果数据来自某种编程语言的字符串字面量,要注意可能有两层转义:语言字符串一层,JSON 字符串一层。
大整数可能丢精度
JSON 支持数字,但 JavaScript 会把它解析成 Number。非常大的整数可能丢失精度。
有风险:
{
"order_id": 12345678901234567890
}
更稳:
{
"order_id": "12345678901234567890"
}
订单号、支付流水、数据库主键这类超过 JavaScript 安全整数范围的 ID,通常应该序列化为字符串。
排错清单
JSON 解析失败时:
- 复制原始响应或文件内容。
- 确认开头是
{、[、"、数字、true、false或null。 - 检查是否是 HTML、日志前缀、warning 或空响应。
- 删除尾逗号和注释。
- 只在确定是字符串时,把单引号改成双引号。
- 检查字符串里的转义。
- 大整数 ID 改用字符串。
相关工具
用 JSON 格式化工具 校验和格式化 payload。如果 JSON 里包含 URL 字段,先用 URL 编码解码工具 处理;如果包含 Base64 字段,单独用 Base64 工具 解码,不要直接判断整个 API 响应坏了。