JSON.parse: unexpected token 的 5 种原因和解决办法
一句话结论:JSON.parse 报 unexpected token 说明传进去的不是合法 JSON——要么格式错了,要么根本不是 JSON(比如接口返回了 HTML 错误页)。
先看错误信息里的位置
现代浏览器的报错会带上位置,例如:
SyntaxError: Unexpected token '}' in JSON at position 12
position: 12 就是出错字符的下标,把它前后的内容截出来看,往往一眼就能发现多逗号或少引号。
5 种常见原因
1. 尾随逗号
{
"name": "张三",
"age": 28,
}
最后一个字段后面多了逗号。JavaScript 允许,JSON 不允许——这是最常见的一种。
2. 单引号或没引号的键
{ name: '张三' }
JSON 的键和字符串必须用双引号,单引号和无引号都不行。
3. 注释
{
// 这是注释
"name": "张三"
}
JSON 标准不支持注释。需要注释可以用 JSON5,但发给程序前要转换。
4. 不可见字符 / BOM
从网页、Excel、记事本复制的内容可能带有 BOM(EF BB BF)或全角空格。肉眼看不见,但解析器会当成非法字符。解决办法是先 trim() 并去掉 BOM:
const clean = text.replace(/^\uFEFF/, '').trim()
JSON.parse(clean)
5. 返回的根本不是 JSON
接口出错时常常返回一段 HTML(404 页面、网关报错页),此时报错是:
Unexpected token '<', "<!DOCTYPE "... is not valid JSON
看到 < 就要先怀疑接口状态码。打开浏览器网络面板,看这个请求的 status 和响应头 Content-Type:
- status 不是 200 → 接口本身失败
Content-Type是text/html→ 返回的是页面不是 JSON
快速定位流程
- 打印原始响应(不要先
JSON.parse) - 看前 100 个字符是不是
{或[ - 不是 → 接口问题,查状态码
- 是 → 粘到「JSON 格式化」工具里,它会直接指出第几行第几列出错
- 修好后再
JSON.parse
防御性写法
async function safeJson(url) {
const res = await fetch(url)
const text = await res.text()
if (!res.ok) throw new Error(`HTTP ${res.status}: ${text.slice(0, 120)}`)
try {
return JSON.parse(text)
} catch (e) {
throw new Error('返回的不是合法 JSON:' + text.slice(0, 120))
}
}
关键是先拿到文本再解析,这样出错时能打印原始内容,而不是只看到一个位置数字。
常见问题
unexpected token < 是什么意思?
说明返回的是 HTML 而不是 JSON,通常是接口 404、网关报错或登录跳转页。先检查状态码。
unexpected end of JSON input 是什么原因?
数据被截断了——括号没闭合、响应没传完或读取了空字符串。先打印原始文本长度确认。
怎么快速找到 JSON 的语法错误?
把内容粘到 JSON 格式化工具里,它会指出具体行列;也可以先用 JSON.parse 捕获异常并打印错误信息。