How to Fix Invalid JSON: Common Errors & Solutions
Diagnose and fix the 10 most common JSON errors developers encounter. Each error includes before/after code examples and a clear explanation of why it happens.
为什么 JSON 解析失败
JSON 看起来简单——确实如此——但它的严格性正是让人困惑的原因。与 JavaScript 对象字面量不同,JSON 对语法的简化没有容忍度。没有尾随逗号。没有单引号。没有注释。每一个偏差都会导致解析错误,而错误信息通常没有帮助:Unexpected token 或 JSON.parse: expected ',' or '}' 在第 1 行。
本指南涵盖了开发人员在实际工作中遇到的 10 种最常见的 JSON 错误。每个错误都包括损坏的 JSON、解析器拒绝的原因以及修正后的版本。将此页面添加到书签——你会再次回到这里。
自己试试: 将损坏的 JSON 粘贴到我们的 JSON 修复 工具中,以立即自动修复大多数这些错误。
错误 1:尾随逗号
这是最常见的 JSON 错误。JavaScript 允许对象和数组中的尾随逗号,因此开发人员自然会以相同的方式编写 JSON。但 JSON 不允许它们。
损坏的:
{
"name": "Alice",
"age": 30,
}
修复后:
{
"name": "Alice",
"age": 30
}
30 后的尾随逗号导致解析器期望另一个键值对。当它发现一个闭合大括号时,它就会抛出错误。在每个对象和数组的最后一项后删除逗号。
错误 2:使用单引号而不是双引号
JSON 要求键和值都使用双引号。单引号是 JavaScript 的特性,JSON 解析器会直接拒绝。
损坏的:
{
'name': 'Alice',
'city': 'Portland'
}
修复后:
{
"name": "Alice",
"city": "Portland"
}
这通常发生在从 JavaScript 代码或 Python 字典(也使用单引号)复制对象字面量时。将 ' 替换为 " 可以修复,但要小心包含撇号的字符串——那些需要转义。
错误 3:未加引号的键
JavaScript 允许你写 { name: "Alice" } 而不加引号。JSON 不允许。每个键必须是一个双引号字符串。
损坏的:
{
name: "Alice",
age: 30
}
修复后:
{
"name": "Alice",
"age": 30
}
这通常出现在手动编写 JSON 或复制 JavaScript 对象而不进行转换时。一些编辑器和 API 调试工具会乐于显示未加引号的键,掩盖问题,直到你尝试在其他地方解析文件。
错误 4:JSON 中的注释
JSON 不支持注释——既不支持 // 单行注释,也不支持 /* */ 块注释。这是格式最令人沮丧的限制之一,尤其是对于配置文件。
损坏的:
{
// 数据库设置
"host": "localhost",
"port": 5432 /* 默认 PostgreSQL 端口 */
}
修复后:
{
"host": "localhost",
"port": 5432
}
如果你需要在配置文件中添加注释,可以考虑使用 JSONC(带注释的 JSON),VS Code 和 TypeScript 原生支持,或者切换到 YAML 或 TOML。对于标准 JSON,在解析之前删除所有注释。
错误 5:项目之间缺少逗号
在 JSON 对象中添加新字段时,容易忘记将其与前一个字段分隔的逗号。解析器看到两个连续的值没有分隔符而无法解析。
损坏的:
{
"name": "Alice"
"age": 30
}
修复后:
{
"name": "Alice",
"age": 30
}
错误信息通常指向缺少逗号后的行,这可能会误导。如果你看到 Unexpected string 或 Expected comma,请查看报告位置上方的行。
错误 6:缺少闭合括号或大括号
在大型 JSON 文件中,括号不匹配很难发现。缺少 ] 或 } 会导致解析器读取超出结构预期的结束位置,产生与实际问题相去甚远的混淆错误。
损坏的:
{
"users": [
{ "name": "Alice" },
{ "name": "Bob" }
}
修复后:
{
"users": [
{ "name": "Alice" },
{ "name": "Bob" }
]
}
修复方法:使用带括号匹配的编辑器(VS Code 高亮显示匹配的对)或一个 JSON 验证器,它会报告不匹配的确切位置。
错误 7:undefined、NaN 或 Infinity
这些是有效的 JavaScript 值,但没有 JSON 表示。JSON.stringify 会默默地将 undefined 转换为 null(或完全省略该键),但如果你手动写这些值,解析器会拒绝它们。
损坏的:
{
"score": NaN,
"callback": undefined,
"limit": Infinity
}
修复后:
{
"score": null,
"callback": null,
"limit": null
}
将 undefined 和 NaN 替换为 null,或者如果缺少值在语义上是合适的,则完全省略该键。对于 Infinity,可以考虑使用一个哨兵数字或字符串表示,如 "Infinity",并在应用程序代码中处理它。
错误 8:数组最后一项后的额外逗号
这是错误 1 的数组版本。它在手动编辑的 JSON 文件中经常出现,尤其是在删除或重新排序项目后。
损坏的:
{
"colors": [
"red",
"green",
"blue",
]
}
修复后:
{
"colors": [
"red",
"green",
"blue"
]
}
模式是相同的:"blue" 后的逗号告诉解析器期望另一个元素。它发现 ] 而报告错误。在从 JSON 数组中删除项目时,始终检查新最后一项是否有尾随逗号。
错误 9:智能引号(弯曲引号)
这个错误很隐蔽。当你从 Word 文档、Slack 消息或博客文章中复制 JSON 时,你的系统可能会默默地将直引号(")替换为排版的“智能”引号(\u201C 和 \u201D)。它们看起来几乎相同,但完全是不同的字符。
损坏的:
{
\u201Cname\u201D: \u201CAlice\u201D,
\u201Ccity\u201D: \u201CPortland\u201D
}
修复后:
{
"name": "Alice",
"city": "Portland"
}
错误信息通常是 Unexpected token 在位置 1 或 2,这让人困惑,直到你意识到引号字符是错误的。修复方法:将所有弯曲引号替换为直双引号。在紧急情况下,可以在纯文本编辑器中手动重新输入引号。
为了防止这种情况,始终使用代码编辑器(而不是富文本编辑器)来编写 JSON。如果你经常在应用程序之间粘贴,请在操作系统的键盘设置中禁用“智能引号”。
错误 10:BOM(字节顺序标记)字符
BOM 是一个不可见字符(U+FEFF),某些 Windows 文本编辑器在文件开头插入它以指示编码。JSON 解析器将其视为在开括号之前的意外字符,并立即失败。
症状:
SyntaxError: Unexpected token \uFEFF in JSON at position 0
在大多数编辑器中,你无法看到 BOM——它确实是不可见的。要检测它,可以在十六进制编辑器中打开文件,查看开头的字节 EF BB BF(UTF-8 BOM)。
修复方法:
- 在 VS Code 中,点击状态栏中的编码指示器,选择“以编码保存”→“UTF-8”(无 BOM)。
- 在命令行中:
sed -i '1s/^\xEF\xBB\xBF//' file.json - 在 Node.js 中,在解析之前去除它:
const clean = text.replace(/^\\uFEFF/, "");
快速参考:所有 10 个错误
| # | 错误 | 原因 | 修复 |
|---|---|---|---|
| 1 | 尾随逗号 | 最后一个属性/元素后的逗号 | 删除尾随逗号 |
| 2 | 单引号 | 使用 ' 而不是 " | 替换为双引号 |
| 3 | 未加引号的键 | 键没有双引号 | 用双引号包裹所有键 |
| 4 | 注释 | JSON 中的 // 或 /* */ | 删除所有注释 |
| 5 | 缺少逗号 | 项目之间没有逗号 | 在项目之间添加逗号 |
| 6 | 缺少括号/大括号 | [ 或 { 没有闭合 | 添加缺失的闭合字符 |
| 7 | undefined / NaN / Infinity | JSON 中的 JS 特有值 | 替换为 null 或字符串 |
| 8 | 数组中额外的逗号 | 数组中的尾随逗号 | 删除尾随逗号 |
| 9 | 智能引号 | 来自 Word/Slack 的弯曲引号 | 替换为直双引号 |
| 10 | BOM 字符 | 文件开头的不可见 U+FEFF | 重新保存为无 BOM 的 UTF-8 |
防止 JSON 错误
修复错误是好的,但不在一开始就创建它们更好。以下是保持 JSON 干净的习惯:
- 绝不要手动编写 JSON。 使用
JSON.stringify或你语言的等效方法从代码生成它。序列化器定义上会生成有效的 JSON。 - 使用 JSON 友好的编辑器。 VS Code、JetBrains IDE 和 Sublime Text 都会实时高亮显示 JSON 语法错误。如果你看到红色波浪线,请在保存之前修复它。
- 在 CI 中验证。 在构建管道中添加一个验证步骤,解析所有 JSON 文件并在错误时失败。一行 shell 脚本就可以做到:
find . -name "*.json" -exec python -m json.tool {} \\; - 对于配置使用 JSONC。 如果你需要注释,请在支持的地方使用 JSONC(
.jsonc扩展)。TypeScript、VS Code 和许多其他工具都原生支持它。
何时使用自动修复
有时你收到的 JSON 超出了你的控制范围——来自构建不良服务的 API 响应、由遗留软件导出的文件,或由非技术团队成员粘贴的块。在这些情况下,手动修复既繁琐又容易出错。
自动修复工具可以在一次操作中修复上述大多数错误。它们解析损坏的输入,推断预期的结构,并生成有效的 JSON。这对于常见问题,如尾随逗号、单引号和未加引号的键,效果很好。
权衡是,自动修复会做出假设。如果 JSON 严重格式错误——缺少大部分内容或结构模糊——工具可能会猜错。在生产中使用之前,始终验证修复后的输出。
自己试试: 将损坏的 JSON 粘贴到我们的 JSON 修复 工具中,以自动修复常见错误,或使用 JSON 验证器 精确定位问题所在。