JSON 尾逗号为什么会报错
结论:尾逗号在 JavaScript 里合法,在 JSON 里是语法错误。本文给出报错原文、RFC 依据、三种改法,以及为什么不要靠「删逗号」蒙混过接口。

结论:JSON 全文不允许尾逗号,报错时先用格式化工具定位到最后一个逗号并删除;需要宽松语法时只在本地用 JSON5 或 JSONC 解析,发给其他系统仍必须输出标准 JSON。
因为标准不允许。
{
"name": "demo",
"size": 12,
}
JSON.parse 会抛 SyntaxError: Expected double-quoted property name in JSON at position 34。
Chrome 的措辞是 Unexpected token } in JSON at position 34,Node 更啰嗦一点,但指向的都是同一个位置:} 前面那个逗号。
报错到底在说什么
RFC 8259 的对象语法是这样写的:
object = begin-object [ member *( value-separator member ) ] end-object
方括号表示「可省略」,星号表示「零次或多次」。翻译成人话:成员之间才需要逗号,最后一位后面直接跟 }。
解析器读到逗号时已经准备好接收下一个成员名,结果下一个字符是 },于是判定语法错误。
数组同理。[1, 2, 3,] 一样报错,只是错误位置在 ] 上。
为什么大家总觉得尾逗号是合法的
因为 JavaScript 对象字面量从 ES5 起就允许尾逗号,Python 的列表、Go 的复合字面量也允许。 写代码时习惯了,切换到 JSON 就顺手带上。另外不少编辑器会自动补逗号,粘贴时也很容易多出来。
还有一个更隐蔽的来源:手写模板拼 JSON。字符串拼接时循环条件写成 i <= length,最后一个元素后面就多了一个逗号。
三种改法
改法一:删掉。 手工场景下最直接。用本站的 JSON 格式化 粘贴进去,错误会定位到行列,改完立刻能看到结果。
改法二:用 JSON5 或 JSONC 解析。 这两种超集允许尾逗号,适合本地配置。但如果这段数据要发给接口、写进数据库、进消息队列,就不该指望对方也支持超集——JSON5 解析器 只解决「我这边能读」,解决不了「对方也能读」。
改法三:别手拼。 生成端一律用 JSON.stringify、json.dumps、Jackson 之类的序列化器,让库负责逗号。手拼字符串是最常见的尾逗号来源,也顺带解决了转义问题。
顺手检查这几处
| 位置 | 常见错误 |
|---|---|
| 循环拼接 | 条件写成 <=,末尾多一个逗号 |
| 复制粘贴 | 从 JS 文件粘对象字面量,带上了尾逗号 |
| 模板引擎 | 模板里写死逗号,循环体里又拼一次 |
| 手工编辑 | 删了最后一个字段,逗号没跟着删 |
常见问题
为什么 JavaScript 里能写尾逗号,JSON 里不行?
JavaScript 对象字面量从 ES5 起就允许尾逗号,Python 列表和 Go 复合字面量也允许,所以写代码时很容易顺手带上。JSON 依据 RFC 8259,只允许成员之间有逗号,最后一个成员后面直接跟 } 或 ]。把 JS 文件里的对象字面量粘进 .json 文件,就是最常见的来源。
是否可以用 JSON5 或 JSONC 兼容尾逗号?
可以,但只适合本地配置。这两种超集允许尾逗号,解析器能读;一旦数据要发给接口、写进数据库或进消息队列,对方按标准 JSON 解析仍会报错。要跨系统传输就必须在输出端生成标准 JSON。
尾逗号报错后应该先检查哪里?
先看错误信息给出的位置,通常是 } 或 ] 前面的那个逗号。再检查三个常见来源:循环拼接把条件写成 i <= length、从 JS 文件复制粘贴的对象字面量、以及模板里写死逗号后又拼了一次。用格式化工具粘贴一次,行列会直接指到出错位置。