Unexpected token报错:原因、定位与修复

JSON解析时看到Unexpected token,通常不是这个字符本身有问题,而是它前面的引号、逗号、括号,或者数据来源出了问题。本文按报错里的关键字逐个拆解,并给出可直接复制的修复示例。

本文覆盖:Unexpected token in JSON、Unexpected token < in JSON at position 0、Unexpected token o in JSON at position 1、Unexpected token u in JSON at position 0、Unexpected token ' in JSON等常见变体。

30秒判断

报错里的关键字大概率原因
<接口返回了HTML或XML,不是JSON
[object Object]传入了已经解析过的对象
undefined传入了undefined
'用了单引号
]、}、,尾随逗号、缺少逗号或括号不匹配
不可见字符文件带BOM

最快修复

  1. 把原始JSON和完整报错粘贴到JSON校验工具。
  2. 工具会标出错误所在的行和列。先检查报错位置前1至2行。
  3. 如果是尾随逗号、单引号、注释、BOM等常见问题,点“修复”。否则按下面的关键字对照表排查。

本站数据在浏览器本地处理,不上传服务器。修复需要手动点击,不会自动改你的数据。

先看懂报错:position、行号列号和新旧文案

JSON解析器会逐个字符读取输入。遇到不符合语法的字符时,解析器抛出Unexpected token。报错里的position是解析器失败的位置,真正的原因常常在它前面1至2行。

V8是Chrome、Edge、Node.js使用的JavaScript引擎。JSON.parse的报错文案在不同版本中改过,下面两种写法都可能出现。

场景较早的Chrome/Node较新的Chrome/Node
单引号 Unexpected token ' in JSON at position 14 Unexpected token ''', ... is not valid JSON
HTML响应 Unexpected token < in JSON at position 0 Unexpected token '<', "<!DOCTYPE html>..." is not valid JSON
传入对象 Unexpected token o in JSON at position 1 "[object Object]" is not valid JSON
传入undefined Unexpected token u in JSON at position 0 "undefined" is not valid JSON
对象尾随逗号 Unexpected token }(旧版常见) Expected double-quoted property name in JSON at position 53 (line 5 column 1)

表中的位置和行列以实际输入为准。单引号在键名位置时,较新V8通常报Expected property name or '}';在值位置时报Unexpected token '''。Firefox和Safari的报错文案不同,但原因和修复方法相同。

按报错关键字查原因

先按报错里出现的关键字分流,再进入下面的详细原因。新旧文案都能用这张表。

报错关键字常见原因最小示例修复
< 服务端返回HTML或XML <!DOCTYPE html> 查状态码、Content-Type、接口地址、登录跳转、代理
[object Object] 传入对象 JSON.parse({a:1}) 直接使用对象,需要字符串用JSON.stringify
undefined 传入undefined JSON.parse(undefined) 检查变量、响应体、localStorage
' 单引号 {'a':1} 改成双引号,或用修复
Expected property name or '}' 单引号键名、注释、未加引号的key {'a':1} 改双引号、删注释、给key加引号
Expected double-quoted property name 对象尾随逗号 {"a":1,} 删除最后一个逗号
]、}、, 尾随逗号、缺逗号、括号不匹配 {"a":[1,2} 删除多余逗号或补齐括号
不可见字符 BOM \uFEFF{"a":1} 另存为无BOM,或使用replace(/^\uFEFF/,'')
\ 非法转义 {"path":"C:\Users"} 双反斜杠C:\\Users
NaN、Infinity 非法数字 {"n":NaN} 用null或字符串
@、= Java toString等非JSON文本 User@hash{id=1} 先转标准JSON,当前一键修复不处理

五种最高频原因与修复

Unexpected token <:接口返回了HTML

这是最常见、也最容易误判的一种。<不是JSON里的字符,它通常意味着你拿到的是一个HTML页面。

Unexpected token '<', "<!DOCTYPE html>..." is not valid JSON

最小复现:

const res = await fetch('/api/user');
const data = await res.json();

先别改JSON,先看请求:

const res = await fetch('/api/user');
const raw = await res.text();
console.log(res.status);
console.log(res.headers.get('content-type'));
console.log(raw.slice(0, 200));

常见原因:

  • 接口地址写错,命中了前端路由,返回index.html。
  • 登录态失效,被重定向到登录页。
  • 后端返回500,响应体是HTML错误页。
  • Nginx或网关把JSON响应替换成了HTML。
  • 本地代理配置错误。

修复:确认status是200,Content-Type包含application/json,再解析。不要把HTML当JSON修。可以先把真实响应粘贴到JSON校验工具,确认它到底是不是JSON。

尾随逗号

最小复现:

{
  "name": "Alice",
  "age": 30,
  "city": "Tokyo",
}

报错通常包含Expected double-quoted property name,较新V8可能带(line 5 column 1)。

修复:删除最后一个逗号。

{
  "name": "Alice",
  "age": 30,
  "city": "Tokyo"
}

也可以直接粘贴到JSON格式化工具,点“修复”。

单引号

最小复现:

{
  "name": "Alice",
  "city": 'Tokyo'
}

报错通常包含Unexpected token '''。

如果单引号出现在键名位置,较新V8通常报Expected property name or '}'。

修复:JSON只允许双引号。改成双引号,字符串里的撇号需要转义。

{
  "name": "Alice",
  "city": "Tokyo"
}

单引号、尾随逗号和注释混在一起时,粘贴到JSON格式化工具点“修复”更快。

注释

最小复现:

{
  // 用户名
  "name": "Alice"
}

报错通常包含Expected property name or '}'。

修复:标准JSON不支持注释。删除注释,或改用YAML、JSONC、JSON5。浏览器原生JSON.parse不接受注释。需要临时处理时,可以粘贴到JSON格式化工具点“修复”。

BOM

最小复现:文件开头有不可见的U+FEFF,十六进制为EF BB BF。

\uFEFF{"name":"Alice"}

报错位置通常在0,较新V8会引用一个看起来像空白的字符。

修复:另存为UTF-8无BOM,或在代码里去掉。

const cleaned = text.replace(/^\uFEFF/, '');
JSON.parse(cleaned);

也可以直接粘贴到JSON格式化工具点“修复”。

其他常见写法

场景示例处理
未加引号的key{name:"Alice"}给key加双引号,可用修复
括号不匹配{"a":[1,2}补齐]或}
非法转义{"path":"C:\Users"}使用C:\\Users,或用JSON.stringify生成
NaN或Infinity{"n":NaN}改成null或字符串
前导零{"code":007}改成7
Python dict{'a': True, 'b': None}本站修复可转标准JSON
Java toStringUser@hash{id=1}当前一键修复不处理,先转标准JSON

不是语法错:空响应、截断和类型错误

有些Unexpected token并不是JSON语法问题,而是解析之前的数据就错了。

  • Unexpected end of JSON input:空字符串、响应被截断、文件没写完。
  • JSON.parse(undefined):传入undefined,报错里可能包含undefined或旧版u。
  • JSON.parse(object):传入对象,报错里包含[object Object]或旧版o。
  • 服务端返回HTML:报错里包含<。

安全的解析顺序是先读文本、看状态码,再解析:

const res = await fetch('/api/user');
const raw = await res.text();

if (!res.ok) {
  console.error(`HTTP ${res.status}`, raw.slice(0, 200));
} else if (!raw) {
  console.error('响应体为空');
} else {
  try {
    const data = JSON.parse(raw);
  } catch (e) {
    console.error('JSON解析失败:', e.message, raw.slice(0, 200));
  }
}

怎么避免再次出现

  • 用JSON.stringify()生成JSON,不要手拼字符串。
  • 解析前先看response.status和Content-Type。
  • 先response.text(),打印前200个字符,再JSON.parse。
  • 编辑器开启JSON校验,CI加一条python -m json.tool或jq empty。
  • 不确定数据来源时,先校验再处理。

本站怎么帮你

  • 标出错误所在的行和列。
  • 中文提示,不要求读者先理解V8英文文案。
  • 一键修复尾随逗号、单引号、注释、未加引号的key、BOM、Python dict、截断JSON。
  • 格式化和压缩保留大整数,不会把订单号悄悄改写。
  • 数据在浏览器本地处理,不上传服务器。
  • 修复需要手动点击,不会自动改用户数据。

常见问题

Unexpected token <是什么意思?

服务端返回了HTML或XML,不是JSON。常见于接口地址写错、登录态失效被重定向、后端500返回错误页、Nginx或网关改写响应。先看Network里的状态码和Content-Type,不要先改JSON。

Unexpected token o怎么解决?

传给JSON.parse的是一个对象,被隐式转成了[object Object]。如果数据已经是对象,直接使用。如果需要字符串,用JSON.stringify。

Unexpected token u怎么解决?

传入了undefined。常见于localStorage.getItem返回null、接口没有响应体、变量名写错。先判断空值,再解析。

Unexpected token '单引号怎么修?

JSON只允许双引号。把单引号换成双引号,字符串里的撇号需要转义。也可以用本站的一键修复。

JSON可以有注释或尾随逗号吗?

标准JSON不允许。JSONC和JSON5允许注释和尾随逗号,但浏览器原生JSON.parse不支持。需要注释时改用YAML或JSONC工具。

为什么本地能解析,线上报错?

线上可能返回了HTML错误页、被网关改写、编码不同或响应被截断。打印response.status、Content-Type和raw.slice(0, 200)再判断。

修复后大数字会变吗?

本站格式化和压缩使用LosslessJSON,保留原数字。修复后仍建议检查关键ID。转XML时大整数可能不保真,长ID建议先作为字符串处理。

本站会上传我的JSON吗?

格式化、校验、修复在浏览器本地执行,不会主动上传输入内容。页面会加载统计脚本,你可以打开Network面板验证请求。输入默认保存在本机localStorage,公共电脑用完点“清空”。