报错排查2026-11-01

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

快速定位流程

  1. 打印原始响应(不要先 JSON.parse)
  2. 看前 100 个字符是不是 { 或 [
  3. 不是 → 接口问题,查状态码
  4. 是 → 粘到「JSON 格式化」工具里,它会直接指出第几行第几列出错
  5. 修好后再 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 捕获异常并打印错误信息。

用工具试试