约 7 分钟阅读更新于

JSON 调试最常见的 10 个错误:为什么本地没问题、线上却解析失败

作者:Safe Local Tools 编辑组

**JSON 出错并不神秘,绝大多数失败都落在同一批规则上。**先搞清「文本格式」与「运行时对象」的差别,你就能把大量“灵异解析错误”还原成结构、编码或契约层面的具体问题。

当你在日志里看到 Unexpected token,或在流水线里发现配置文件“偶尔读不出来”,根因往往并不是 JSON 这个概念太难,而是你手里的字符串看起来像 JSON,却不满足 RFC 8259 这套语法(也可以用 维基百科对 JSON 的综述 快速补齐背景)。本文列出十个最常见误区,解释严格解析器为什么会报错,并说明 Safe Local Tools 在浏览器本地处理数据:格式化与检查时不必把敏感负载上传到外部服务器。

OG illustration

为什么「在 Node 里没问题」,一到严格解析就炸

很多前端与后端同栈的团队会把 JSONJavaScript 对象字面量混为一谈。前者是交换数据的受限语法;后者是编程语言的表达方式,带着一堆 JSON 不允许的“写法便利”。

典型路径是:你在脚本里直接写字面量,跑得好好的;一旦写入磁盘、通过 HTTP 交换或交给另一种语言的解析器,就会在边界处失败。浏览器侧的权威参考可以看 MDN 的 JSON.parse() 文档:什么时候抛错、错误意味着什么,写得很直白。

另一个高频因素是复制粘贴链路:IM、邮件客户端或网页会把引号、缩进甚至不可见字符改掉,使你肉眼看到的文本与真实字节不一致。调试时请像保存证据一样保存原始字节,而不是只看语法高亮。

错误 1:对象最后一项后面多了尾随逗号

尾随逗号在不少 JS 写法里是允许的,但 JSON 不允许

{
  "userId": 42,
  "role": "editor",
}

末尾逗号会让严格解析失败。编辑器插件有时依然给你“看起来很正常”的高亮。

**修法:**删掉逗号;或用 JSON.stringify 生成,而不是长期手改巨型文本。

生成型配置(模板拼接)最容易反复引入尾随逗号——最好在 CI 里对所有 fixture 跑一次 JSON.parse

错误 2:字符串用了单引号

JSON 规定字符串必须用双引号;单引号整体无效。

{
  'status': 'ok'
}

这是典型的“写着写着写成 JS”的习惯泄漏。

**修法:**统一替换为双引号,并正确转义内部 "

若你需要临时把现有字面量正规化成文本,可以用 JS 的序列化边界来保证输出合法:

const repaired = JSON.stringify({ status: "ok" });

错误 3:字符串里夹了未转义的换行与控制字符

JSON 字符串里不能直接夹裸换行;需要 \n 等形式(或改用 base64 等策略,视场景而定)。

**症状:**报错指向某个很长的字段中段,提示非法控制字符。

**修法:**在边界处序列化,不要把整段日志原样粘进字符串。

错误 4:undefinedNaNInfinity 之类“看起来像值但不是 JSON”

JSON 只有 null、布尔、数字、字符串、数组和对象。

常见踩坑:

  • undefined:有的序列化逻辑直接丢弃键,有的则产出非法文本
  • NaN / Infinity:不是合法 JSON token

**修法:**显式映射成 null、字符串,或直接省略字段。

监控指标对象特别容易“偶尔除以零”,从而间歇性写出非法 JSON。

错误 5:重复键:能解析也不代表正确

不同栈对重复键的处理不一致:有的拒绝,有的保留首次或末次。

{
  "retry": false,
  "retry": true
}

即便解析通过,业务语义也可能随机漂移。

**修法:**把重复键当作契约缺陷;对配置文件做 lint。

错误 6:写了 ///* */ 注释

JSON 不支持注释。但人类确实想在配置里写说明,于是“带注释的 JSON”到处都是。

**修法:**只在明确支持 JSONC 的工具链使用;否则把注释移到 README 或单独字段。

错误 7:编码与 BOM 引发的“第 0 列就很怪”

Web API 事实标准是 UTF‑8。错误的 BOM 或混用编码可能让解析器一上来就失败。

**修法:**统一 UTF‑8(尽量避免 BOM);特别留意 Excel 导出与老旧数据库 dump。

错误 8:巨型 prettify JSON:不一定是语法错,但会拖累定位问题

体积暴涨会让 diff 难读,也会让人们在评审时遗漏一小处逗号变更。

**修法:**传输链路压缩空白;人类阅读再格式化。

错误 9:契约漂移:字段类型悄悄换了

例如 userId 从数字变成字符串:松散的消费端可能默默转型,严格的则在边界失败。

**修法:**版本化 API;在入口处校验形状。

错误 10:调试 JSON 时把密钥粘到了工单里

这是安全意识问题:你越急着还原结构,越容易复制整块对象。

这正是 本地优先工具 的意义:Safe Local Tools 强调浏览器本地处理,适合你先用脱敏样本迭代结构问题,而不是把机密发往未知的格式化网站。

一套能真正收尾的调试流程

  1. 保存失败时的原始字节(不要先用编辑器自动排版后再反馈)。
  2. 利用报错位置定位区间。
  3. 二分删减找出最小失败片段。
  4. 有 schema 就校验(OpenAPI / JSON Schema)。

修复后建议再走一遍生产侧的序列化路径:二次 JSON.stringify(把字符串又 stringify 一次)这类问题往往在编辑器里看不出来。

跨语言互操作里的隐蔽坑

JSON “通用”不等于语义完全一致:超大整数在 JS number 里可能丢精度;对象键无序但人类评审依赖顺序;日期字符串若不约定 ISO‑8601 与时区就会歧义。把契约写下来,比口头约定“大家都懂 JSON”可靠得多。

对接三方 SDK 时也要警惕“过度聪明的自动反序列化”,它会让你很晚才发现负载形状其实在漂移。

顺理成章地下一步:先格式化,再验证

当你知道哪些写法必定非法,剩下的工作就是机械清理:校验结构、统一引号、去掉注释与尾随逗号、对比前后差异。这些步骤在 Safe Local Tools 上可以更快完成,而且默认把你的内容留在本机处理链路里。

想把一团乱麻整理成可解析、可评审的 JSON?现在就 试用 JSON 格式化工具 →