JSON 格式 7 个必踩的坑

· 约 3 分钟 {} JSON 工具

“Unexpected token in JSON” 是前后端联调最常见的报错。90% 的情况都栽在下面这 7 个坑里,每一个都附修复方案。

1. 尾逗号

{
  "a": 1,
  "b": 2,    ← 这个逗号 JSON 不允许
}

JavaScript 允许,JSON 禁止。处理外部配置文件时想要尾逗号,用 JSON5JSONC(VSCode settings.jsontsconfig.json 都是 JSONC 方言)。

2. 单引号

{'name': 'Alice'}    ← 错
{"name": "Alice"}    ← 对

JSON 字符串必须双引号,键也必须带双引号。Python 的 str(dict) 默认输出单引号——要用 json.dumps(),不是 str()

3. 注释

JSON 规范不支持 ///* */。Crockford 的解释是”我看到有人用注释给 parser 塞指令,干脆取消”。

替代约定:加一个 _comment 字段:

{
  "_comment": "开发环境配置",
  "api": "https://dev.example.com"
}

或改用 JSONC / JSON5 / YAML。

4. 大整数精度丢失

{"orderId": 9007199254740993}

JS 的 JSON.parse 会把它变成 9007199254740992——最后一位丢了。Twitter 早年就栽过这个坑,把推文 ID 改回字符串返回。后端返回超过 2^53 的整数一律转字符串

{"orderId": "9007199254740993"}

需要算术的场景前端 BigInt("900...") 处理。

5. 特殊字符没转义

换行、Tab、双引号、反斜杠在字符串里必须转义:

{"msg": "line1\nline2"}       换行用 \n
{"msg": "say \"hi\""}         双引号用 \"
{"msg": "path\\to\\file"}     反斜杠用 \\

中文不用转义,直接 "msg": "你好" 合法(前提文件是 UTF-8)。历史上的 \u4f60\u597d 形式是为了躲 ASCII-only 的传输通道,现在已无必要——除非接收方明确要求。

6. UTF-8 BOM

Windows 记事本”另存为 UTF-8”会在文件开头加 3 字节 EF BB BF(BOM)。JSON 规范要求不带 BOM,否则解析器会在第 1 列就报 “Unexpected token ï”。

查和去:

file config.json                          # 看是否 "UTF-8 with BOM"
sed -i '1s/^\xEF\xBB\xBF//' config.json   # 去 BOM

或 VSCode 右下角切 UTF-8 without BOM 重存。

7. NaN / Infinity / undefined

JSON.stringify({a: NaN})         // '{"a":null}'
JSON.stringify({a: Infinity})    // '{"a":null}'
JSON.stringify({a: undefined})   // '{}'     ← 字段直接消失

这三个值不是合法 JSON。JSON.stringify 默默改成 null 或丢掉字段——接收端以为”字段不存在”,其实后端算出了 NaN,bug 就这样埋下。

约定:遇到这三种情况显式传 null + errorReason 字段,或干脆传 "NaN" 字符串,让问题浮出水面。

“标准 JSON 还是 JSON 方言”速查

格式尾逗号注释单引号无引号键典型场景
JSON (RFC 8259)API 传输、数据交换
JSONCVSCode 配置、tsconfig
JSON5手写配置
YAMLK8s、GitHub Actions

API 传输永远用标准 JSON;配置文件按工具支持度选方言。

排错顺序

  1. 贴到格式化工具,看报错定位到哪一行
  2. 检查末尾是否截断(下载不完整 / 字段太长被截)
  3. 检查开头是否有 BOM 或多余空白
  4. 搜尾逗号:grep -n ',\s*[}\]]' file.json
  5. 搜单引号:grep -n "'" file.json
  6. 大数值转字符串重传
  7. 确认 NaN / Infinity / undefined 的出处

排完这 7 步,剩下不到 5% 的问题基本是字符编码不一致。

❓ 常见问题

为什么 JSON 不允许尾逗号?

JSON 规范(RFC 8259)明确禁止——Douglas Crockford 想保持"最小可能的规范",拒绝了所有模糊语法。JavaScript 的对象字面量 `{a:1,}` 允许尾逗号,但 `JSON.stringify` 输出时会去掉。配置文件想要尾逗号和注释,用 JSON5 / JSONC(VSCode 的 `settings.json` 就是 JSONC)。

JSON 里 Number 最大能表示多少?

JSON 规范没定上限,但事实标准是 JS 的双精度浮点(IEEE 754),安全整数上限是 2^53-1 ≈ 9.007×10^15。超过会丢精度——18 位雪花 ID、订单号、Long 类型主键都会被改写。后端一律转字符串传,前端用 BigInt 或字符串运算。

JSON 支持日期类型吗?

不支持——JSON 规范只有 string / number / boolean / null / object / array 六种类型。日期一律用 ISO 8601 字符串(`"2026-04-21T10:00:00Z"`)传输,两端自己 parse 成 Date。少数后端直接传时间戳数字也能用,但要明确说清是秒还是毫秒。

JSON 文件开头有看不见的字符,怎么处理?

多半是 UTF-8 BOM(`\uFEFF`,3 字节 `EF BB BF`)——Windows 记事本存 UTF-8 默认加上。JSON 规范要求 UTF-8 且不能带 BOM,`JSON.parse` 会抛 "Unexpected token"。VSCode 右下角切 "UTF-8 without BOM",或 `content.replace(/^\uFEFF/, '')` 手动剥。

{} 打开 JSON 工具 语法高亮 · 格式化/压缩 · JSONPath/JS 表达式 · 50MB 不卡

📖 同一工具的其他教程