看到 Unexpected token in JSON at position 0、JSON Parse Error 或 Invalid JSON Format,不代表解析器坏了。它们都在说明同一件事:程序读到的内容不是一段完整、合法的标准 JSON。
问题可能只是少了一个逗号,也可能是接口返回了 HTML 登录页、空字符串或带 BOM 的文本。下面按“为什么出现、如何定位、如何修复”的顺序排查,并介绍怎样使用 ToolGarden 在线 JSON Validator 快速确认结果。
为什么会出现 JSON Parse Error?
1. position 0 收到的根本不是 JSON
position 0 表示解析器在第一个字符就失败了。接口本应返回以 { 或 [ 开头的 JSON,却可能实际返回以 < 开头的 HTML 错误页、登录页或反向代理提示。此时修改 JSON 语法没有用,应该先检查请求地址、HTTP 状态码和响应正文。
文件开头的 UTF-8 BOM 也是常见原因。这个隐藏字符肉眼看不见,但部分运行时会把它当作 position 0 的非法 token。空响应更常见的提示是 Unexpected end of JSON input,同样需要从数据来源而不是业务字段开始排查。
2. JSON 使用了错误的引号或属性名
{
name: 'Tom',
"message": "He said "hello""
}标准 JSON 不是 JavaScript 对象字面量。属性名和字符串都必须使用双引号,字符串内部的双引号必须写成转义形式。单引号、智能引号、未加引号的 key 和未转义换行都会触发 JSON Syntax Error。
3. Missing comma in JSON
{
"name": "Tom"
"age": 18
}相邻属性或数组元素之间缺少逗号时,解析器通常在第二个属性附近报错。错误位置指向的是“无法继续读取”的字符,真正缺失的逗号往往位于它前一行。
4. 末尾多了逗号
{
"name": "Tom",
"age": 18,
}部分 JavaScript 写法允许尾随逗号,但严格 JSON 不允许。删除最后一个字段后的逗号即可。
{
"name": "Tom",
"age": 18
}5. JSON 被截断或括号没有闭合
下载中断、流式输出未结束、复制内容不完整,都会让 JSON 在字符串、对象或数组尚未闭合时结束。这类问题通常显示 Unexpected end of JSON input 或 JSON Decode Error。重点检查最后一个字符以及 {、[、引号是否成对。
6. 把已经解析的对象再次传给 JSON.parse
JSON.parse 需要接收字符串。如果变量已经是 JavaScript 对象,再次解析时可能先被转换成 [object Object],随后出现 Unexpected token o。先用 typeof 检查输入类型,只有字符串才需要 JSON.parse。
常见错误提示分别代表什么?
| 错误提示 | 最可能的原因 | 先检查什么 |
|---|---|---|
| Unexpected token in JSON at position 0 | 首字符不是合法 JSON,常见于 HTML、BOM 或普通文本 | 查看原始内容的前 80 个字符 |
| Unexpected token < | 服务端返回了 HTML 页面 | 检查状态码、重定向和登录状态 |
| Unexpected token o | 对 JavaScript 对象重复执行 JSON.parse | 检查 typeof input |
| Missing comma in JSON | 属性或数组元素之间少了逗号 | 检查报错位置之前的字段 |
| Invalid JSON Format | 引号、逗号、括号或值不符合标准 | 使用 Validator 检查最早错误 |
| JSON Decode Error | 内容截断、编码异常或语法不完整 | 检查文件编码和结尾 |
| JSON Syntax Error | 解析器遇到非法 token | 查看 line、column 或 position |
如何定位 JSON 错误?
- 保留原始文本。不要一开始就 trim、替换字符或吞掉异常,否则会丢失定位线索。
- 检查数据类型。确认传给 JSON.parse 的值是 string,而不是 object、undefined 或 null。
- 查看首字符和结尾。开头应通常是 { 或 [,结尾应与之对应为 } 或 ]。
- 检查 HTTP 信息。接口数据要同时查看状态码、Content-Type、重定向和原始响应。
- 跳到错误位置。position 是从字符串开头计算的字符偏移量,line 和 column 则是行列位置。
- 先修复第一个错误。后续错误可能只是前一个缺失引号或括号造成的连锁反应。
const response = await fetch("/api/data");
const contentType = response.headers.get("content-type") ?? "";
const raw = await response.text();
console.log({
status: response.status,
contentType,
firstChars: raw.slice(0, 80)
});
if (!response.ok) {
throw new Error("HTTP " + response.status);
}
if (!contentType.includes("application/json")) {
throw new Error("Expected JSON, received " + contentType);
}
const data = JSON.parse(raw.replace(/^\uFEFF/, ""));上面的代码先读取原始文本,再验证状态码和 Content-Type,最后移除可能存在的 BOM 并解析。这样可以把网络响应问题和真正的 JSON 语法问题分开。
错误提示中的 position 往往指向解析器停止的位置,而不是错误开始的位置。例如 Missing comma 可能在下一行字段名处报错,真正需要补逗号的位置却在上一行末尾。定位时要向前检查几个字符。
如何修复 Invalid JSON Format?
先把内容恢复成严格 JSON
- 属性名和字符串统一使用双引号。
- 在相邻属性和数组元素之间补上逗号。
- 删除对象或数组末尾的尾随逗号。
- 补全缺失的引号、右花括号和右方括号。
- 把 Python 的 True、False、None 改为 true、false、null。
- 删除标准 JSON 不支持的注释、undefined、NaN 和 Infinity。
- 转义字符串内部的双引号、反斜杠、换行和控制字符。
接口返回 HTML 时修复源头
如果原始响应以 <!DOCTYPE 或 <html 开头,不要用字符串替换把它“改成 JSON”。应该修正接口地址、认证、代理配置或服务端异常,并确保成功和失败响应都返回明确的状态码与正确 Content-Type。
不要手工拼接 JSON 字符串
动态生成 JSON 时使用 JSON.stringify,而不是用加号拼接字符串。JSON.stringify 会正确处理引号、反斜杠和换行,能从源头减少 Missing comma 和未转义字符。
自动修复后还要验证结构
自动修复适合处理尾逗号、单引号、注释和未加引号的 key,但无法可靠猜测缺失字段或错误嵌套的真实意图。修复后应重新格式化,并抽查关键字段;如果数据有业务约束,再使用 JSON Schema 验证字段类型和必填项。
推荐在线 JSON Validator:ToolGarden
不确定是哪一个字符导致 JSON Parse Error 时,可以使用 ToolGarden(toolgarden.xyz)的在线 JSON Validator。粘贴内容后即可验证语法并格式化结构,比在一整行压缩 JSON 中手工数 position 更快。
- 快速判断内容是不是有效 JSON。
- 格式化嵌套对象和数组,方便检查逗号与括号。
- JSON 校验和格式化在浏览器本地完成,输入内容无需作为文件上传处理。
- 遇到非标准 JSON 时,可继续使用 ToolGarden JSON 修复清洗转换为严格 JSON。
总结
遇到 Unexpected token in JSON at position 0 时,先看原始响应,不要急着改字段。遇到 Missing comma、Invalid JSON Format 或 JSON Syntax Error 时,从最早的错误位置向前检查引号、逗号和括号。修复后再用 ToolGarden 在线 JSON Validator 验证一次,可以避免把仍然损坏的数据带回程序。