先看报错本身
JSON 解析失败的报错信息通常长这样:
SyntaxError: Unexpected token '<' in JSON at position 0
SyntaxError: Unexpected end of JSON input
很多人看到就懵了。其实报错里的 token 类型和 position 已经指明了病因,按下面五类对号入座就行。
一、Unexpected token '<' —— 其实是收到了 HTML
这是最常见的一种。position 0 上是个 <,说明你拿到的根本不是 JSON,而是一个网页。
常见原因:
- 接口地址写错了,请求打到了 404 页面
- 服务端 500 了,返回的是错误页
- 接口需要登录,被重定向到了登录页
- 请求经过代理或公共 WiFi,被插入了认证页面
- 反过来:接口正常,但响应头
Content-Type不是application/json,前端用错了方式解析
怎么查:打开浏览器 DevTools 的 Network 面板,找到这个请求,点开 Response 看原始内容。如果开头是 <!DOCTYPE html> 或者 <html,就确认了。
怎么修:解析之前先校验响应,别直接 JSON.parse。
jsconst res = await fetch(url)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
const text = await res.text()
if (text.trimStart().startsWith('<')) {
throw new Error('接口返回了 HTML 而不是 JSON,检查地址和登录态:' + text.slice(0, 100))
}
const data = JSON.parse(text)
先读成文本再解析,出错时还能把原始响应打出来,比直接 parse 好排查得多。
二、Unexpected end of JSON input —— 响应被截断
意思是 JSON 还没结束就没了。常见于:
- 响应体是空的(接口成功但没返回内容)
- 服务端超时或崩溃,连接中断
- 流式响应没有读完就解析
- 内容太长被中间的网关截断
怎么查:看响应长度是不是 0,或者比预期短很多。也检查一下服务端日志有没有异常。
怎么修:解析前先判断内容非空。
jsif (!text || !text.trim()) {
throw new Error('响应为空')
}
三、Unexpected token '}' 或 ']' —— 逗号引号的问题
JSON 的语法比 JavaScript 对象字面量严格得多,最常见的三处差异:
尾逗号。JavaScript 里允许,JSON 不允许:
js// 合法 JS,但非法 JSON
{ "a": 1, "b": 2, }
单引号。JSON 只认双引号:
js{ 'a': 1 } // 非法,必须写成 { "a": 1 }
字符串里有未转义的特殊字符。反斜杠、双引号、换行都要转义:
js{ "path": "C:\\Users\\test" } // 反斜杠要写成 \\
四、看不见的字符:BOM 头
Windows 上特别常见。记事本、PowerShell 的 Out-File 默认会在文件开头写入一个不可见的 BOM(字节序列 EF BB BF)。
现象很迷惑:报错位置那个 token 看起来是空的,或者显示成一个乱码方块。
怎么确认:用十六进制查看文件开头,或者用工具检查。
怎么修:Node.js 里可以这样剥掉:
jsconst text = fs.readFileSync(path, 'utf8').replace(/^\uFEFF/, '')
怎么避免:编辑器里把编码设成「UTF-8 无 BOM」,PowerShell 用 -Encoding utf8NoBOM。
五、不报错但数据变了:大整数精度丢失
这一类不会抛异常,但更危险——数字悄悄被改掉了。
JavaScript 的 Number 是双精度浮点,能精确表示的整数上限是 2^53 - 1。超过这个范围的 ID(比如雪花算法生成的、或者某些平台的订单号)用 JSON.parse 之后末几位会变成 0。
jsJSON.parse('{"id": 1234567890123456789}')
// => { id: 1234567890123456800 } ← 精度已经丢了
怎么修:让后端把大整数用字符串返回,或者用 JSON.parse 的 reviver 配合 BigInt 处理。这个问题值得单独展开,见 → JSON 大整数精度。
快速定位是哪种
拿不准的时候,把内容粘到 JSON 格式化 里过一遍,它会指出具体在哪一行、哪个位置出错,比对着报错数字数位置快得多。
如果只是想确认一段内容是不是合法 JSON,JSON 格式化的校验模式也能直接给结论。
小结
| 报错 | 病因 |
|---|---|
Unexpected token '<' |
收到了 HTML,不是 JSON |
Unexpected end of JSON input |
响应为空或被截断 |
Unexpected token '}' / ']' |
尾逗号、单引号、未转义字符 |
| token 是空白/乱码 | BOM 头 |
| 不报错但数字变了 | 大整数精度丢失 |