工具拆解

JSON 格式化到底在做什么

格式化不只是加缩进。从词法分析到缩进树,解释 JSON 解析器实际做的事,以及为什么 JSON 不允许注释、为什么错误信息总在某个奇怪的位置。

调接口的时候,返回体常常是一整行:几百个字符挤在一起,嵌套对象和数组套了三层, 想看某个字段的值,得用眼睛在屏幕上从左扫到右。

「格式化」这个动作看起来只是加缩进,但它背后其实是把一串字符重新理解成树, 再按树的深度重新排版。理解这一点,很多奇怪的报错就说得通了。

解析器先做两件事

第一步是词法分析:把字符流切成一个个有意义的 token。 {"a":1} 会被切成 {、"a"、:、 1、} 五个 token。

第二步是语法分析:按 JSON 的语法规则把 token 拼成树。 遇到 就开一个对象节点,遇到 [ 就开一个数组节点, 遇到 就关闭当前对象。这棵树就是格式化要用的结构。

格式化本身反而简单:从根节点往下递归,每深一层就多两个空格(或者一个 Tab), 把每个键值对写到新的一行。所以「格式化」= 解析成树 + 按深度重排, 如果解析这一步失败,格式化根本没开始。

为什么错误信息总在奇怪的位置

因为解析器是边读边判断的。它在读到某个字符时才发现前面有问题, 报错位置通常是「发现问题的地方」,而不是「真正出错的地方」。

几个最常见的:

  • Unexpected token '}' —— 十有八九是对象最后一个键值对后面多了逗号。 解析器读完逗号,期待下一个键名,结果遇到 },就在 } 的位置报错。
  • Unexpected token '' —— 用了单引号。 JSON 规范只认双引号,这一点和 JavaScript 的对象字面量不一样。
  • Unexpected end of JSON input —— 内容被截断了。 通常是复制的时候少复制了几个字符,或者接口返回本身就不完整。
  • Unexpected token / —— 出现了斜杠。JSON 不支持注释。

JSON 为什么不允许注释

这不是疏忽。JSON 的作者 Douglas Crockford 明确说过,加注释会让解析器变复杂, 而且有人会把注释当成配置项来用,最后配置文件变成「注释驱动的编程」。

现实是,很多人确实需要注释:VS Code 的 settings.json 就有注释, TypeScript 的 tsconfig.json 也有。它们用的是 JSONC(JSON with Comments)—— 一个非标准的变种,正式传输数据时仍然会去掉注释再发送。

所以如果你从某个配置文件里复制了一段带 // 的内容,粘进标准 JSON 解析器一定会报错。 这不是工具的问题,是格式的问题。

什么时候该压缩

格式化的代价是体积。一个 10 KB 的 JSON,格式化后可能变成 13~15 KB, 因为每个层级都插入了缩进和换行。

需要压缩的场景很具体:

  • 塞进 URL 参数(空格和换行要额外编码)
  • 写进环境变量或命令行参数
  • 作为字符串常量嵌进代码
  • 接口请求体,能省一点带宽

反过来,日志、配置、调试输出都该保持格式化状态,因为读的人比机器多。

一个小习惯

我给这个工具加了 Ctrl / ⌘ + Enter 直接格式化的快捷键。 原因很实际:粘贴完内容,手还在键盘上,不用去摸鼠标。 这类小动作一天重复几十次,省下来的是注意力。

另外,所有处理都在浏览器里完成。包含敏感字段的接口响应,可以放心粘进来—— 页面没有后端,断网也能用。

打开「JSON 格式化」→ 更多文章