开发工具·7 分钟

开发者必读:JSON 格式化最佳实践

掌握 JSON 格式化最佳实践:避开常见错误、学会校验、格式化与压缩,并配合真实示例搞定 API 数据交互。

什么是 JSON?为什么格式化很重要?

JSON(JavaScript Object Notation)是 Web 事实上通用的数据交换格式。它轻量、易读,几乎所有编程语言都原生支持。无论你是在构建 REST API、存储配置,还是在前端和后端之间传递数据,JSON 几乎都是默认选择。

但"易读"取决于你如何书写它。同一段数据,最小化(minify)后可能是 4 KB 的单行文本;用两个空格缩进美化(pretty-print)后可能变成 8 KB。两者都有效。区别在于:下一个开发者——也包括未来的你——能不能在凌晨两点的故障现场一眼读懂。

好的格式化不只是美观,它直接影响:

  • 可调试性:美化后的负载一眼就能看出结构,嵌套对象一目了然,缺失的字段、笔误都无处遁形。
  • Diff 可读性:在最小化的 JSON 上做代码评审毫无意义。两个空格缩进的 diff 能清楚标出哪些字段变了。
  • 错误定位:解析失败时,行号和列号只有在文档有真实排版的前提下才有意义。
  • 团队协作:统一的风格意味着没人需要先把文件重新格式化一遍才能开工。

简单说,格式化是一种沟通方式,请像对待代码一样对待你的 JSON。

最常见的 JSON 错误

即便是资深开发者也会犯这些错。它们在 JavaScript 里都是合法语法,所以编辑器不会提醒。

末尾多余的逗号

数组或对象最后一个元素后面加逗号,在 JavaScript 里完全合法,但在 JSON 中不允许。

```json // 非法 { "name": "Ada", "age": 36, } ```

修复很简单:删掉那个逗号。大部分 linter 都能发现,如果你的工具不报,换一个。

用单引号包裹字符串

JSON 字符串必须用双引号。单引号是 JavaScript 的约定,不是 JSON 的。

```json // 非法 { 'name': 'Ada' } ```

这种问题经常出现在从 JavaScript 对象字面量或 Python 字典里复制值的时候。键和字符串值都要用双引号。

未加引号的键

JSON 的键必须是字符串,字符串必须加引号。

```json // 非法 { name: "Ada" } ```

注释

JSON 不支持注释。`//` 和 `/ /` 都会解析失败。如果你需要注释,要么用 `"_comment"` 字段,要么换 JSON5/JSONC——但只在生产端用,因为大多数消费者只认严格 JSON。

大括号不匹配

漏写 `}` 或多写 `]` 是 "Unexpected end of JSON input" 这类错误的最常见来源。美化输出是最快的定位方式:眼睛会立刻发现不对称。

如何校验 JSON

校验分两类:语法层面(是不是合法 JSON?)和语义层面(是否符合我期望的结构?)。

语法校验方面,每个现代编辑器都够用。VS Code 会把不合法 JSON 标红。命令行工具 `jq` 会在第一个出错字符处直接报错。在线校验工具能用,但涉及敏感数据时要小心——只粘贴非敏感的样例。

语义校验需要 JSON Schema(下面会讲)或带类型的解析器。在 TypeScript 里,`zod`、`io-ts` 这类库可以描述期望的形状并拒绝不匹配的数据。它们能抓住最糟糕的那类 bug:API 静默地新增了一个字段,或老字段突然变成 `null`,等你的代码在三层之下崩溃时已经太晚。

推荐的工作流:

  1. 调试时把入参 JSON 美化一下。
  2. 在系统边界(控制器、API 客户端、消息处理器)用 schema 校验。
  3. 边界内部一律不再信任。

美化 vs. 压缩

它们是同一枚硬币的两面,都有用,只是用在不同地方。

美化(也称 beautify、expand)会加缩进和换行。适合:

  • 提交到 git 的源文件
  • 开发期要查看的 API 响应
  • 以后可能要回看的日志
  • 文档和示例

压缩会去掉所有空白。适合:

  • 生产环境的 API 响应
  • Token 和 Cookie(JWT、Session)
  • 写入空间有限的数据库或缓存
  • 对每个字节都斤斤计较的网络负载

一条经验法则:开发期美化,生产期压缩。大部分构建工具可以自动完成。临时性工作用免费的 JSON 格式化工具 一次粘贴就能双向转换。

如果你要对比两份 JSON 文档,用 文本 Diff 工具 能高亮标出具体哪些字段变了——比盯着压缩后的输出猜要强太多。

处理嵌套数据

嵌套对象和数组是 JSON 表现力最强的地方——也是 bug 最爱藏身的地方。

几个原则:

  • 保持浅层嵌套。三层以内都没问题,五层就该考虑拆成扁平的列表加外键,或者拆成多个接口。
  • 数组与对象保持一致。有时是数组有时是 `null` 的字段是 `Cannot read property 'map' of null` 的常见来源。事先定好:没数据就返回 `[]`,不要返回 `null`。
  • 需要时让键的顺序稳定。JSON 不规定键的顺序,但解析器和 diff 工具在顺序可预测时表现更好。按字母排序是个稳妥的默认。
  • 警惕超大数组。单个数组里塞一百万条 50 MB 的 JSON 字段值,技术上合法但无法流式处理。考虑改用 NDJSON(每行一个 JSON 对象)或分页 API。

API 中的 JSON:Content-Type 与状态码

如果你做 HTTP API,两个请求头承担了大部分工作:

  • `Content-Type: application/json` —— 告诉客户端(以及中间件)接下来是什么内容。忘了加这个,是线上最常见的 API bug。
  • `Accept: application/json` —— 客户端能接收什么类型。用于内容协商。

响应端,状态码要对得上结果:

  • `200 OK` —— 成功,body 是资源或结果。
  • `201 Created` —— 新建了资源,`Location` 头应指向它。
  • `204 No Content` —— 成功但没有 body(DELETE 常见)。
  • `400 Bad Request` —— 请求格式错误(JSON 非法、缺少必填字段)。
  • `401 Unauthorized` —— 没有有效凭证。
  • `403 Forbidden` —— 凭证有效但权限不够。
  • `404 Not Found` —— 资源不存在。
  • `422 Unprocessable Entity` —— JSON 合法但语义不对(比如年龄为负数)。
  • `500 Internal Server Error` —— 服务端炸了,绝不要把堆栈泄露出去。

一种常见做法是把响应包一层:`{ "data": ..., "error": null }` 或 `{ "data": null, "error": { "code": "...", "message": "..." } }`。这种结构没问题,但不是必须的。无论选哪种,都比每次临时拍脑袋不一致要强。

JSON Schema 入门

JSON Schema 是一套用来描述 JSON 文档形状和约束的词汇。可以把它理解为 JSON 的类型系统。

一个最小化的 schema:

```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "required": ["name", "age"], "properties": { "name": { "type": "string", "minLength": 1 }, "age": { "type": "integer", "minimum": 0 } } } ```

它说明:文档必须是包含非空字符串 `name` 和非负整数 `age` 的对象。你还可以扩展 format(`"format": "email"`)、枚举、正则以及引用其他 schema。

为什么要费这个劲?在边界处校验,能在脏数据扩散之前拦住它。它也充当活的文档:schema 描述的是你的 API 实际接受什么,而不是某人以为它接受什么。

大部分语言都有 JSON Schema 校验器。TypeScript 生态里 `zod` 这类工具越来越流行,因为它们能从 schema 直接生成 TypeScript 类型。

日期、数字、特殊字符的常见坑

JSON 故意做得很克制:它没有日期类型,所以人人都会踩坑。

  • 日期:存 ISO 8601 字符串(`"2026-02-01T12:00:00Z"`)。不要用 `"02/01/2026"` 这种——有歧义还依赖语言环境。
  • 数字:JSON 数字都是十进制,没有整数类型。JavaScript 里超过 2^53 的整数会丢精度,ID 或金额最好用字符串。
  • 布尔:只能是字面量 `true` 和 `false`,写 `"true"` 不会自动转换。
  • Unicode:JSON 字符串是 Unicode,emoji 和中日韩字符都直接能用。但转义序列要清楚:`\n` 是换行,`\\` 是反斜杠,`\u0041` 是 `A`。不确定时,把数据粘到 JSON 格式化工具 里看原始字节。
  • null 与缺失:`{"age": null}` 和 `{}` 含义不同。在你的系统里统一约定"未知"该用哪个。

节省时间的工具

好用的格式化工具,是你用过才发现自己离不开的那种。我们免费的 JSON 格式化工具 完全在浏览器里运行——不上传、不注册、不追踪。粘进去一段压缩负载,立刻得到可读的树结构,复制即可。它一边格式化一边校验,语法错误会直接标注在出错的那一行。

要对比两份 JSON 文档(比如迁移前后的版本),文本 Diff 工具 对任何纯文本都好用,逐行高亮差异。

这些都属于 开发者工具 套件的一部分,专为浏览器内一次性、快速的常用操作而设计。

结论

JSON 格式化是一个小习惯,但会在整个项目周期里持续复利。开发期美化、生产期压缩。边界处校验。数据不只是临时用就老老实实写 schema。日期用 ISO 8601,大数字用字符串,`null` 也要用得有意义。

这些事都不性感,但下次出问题时都能帮你省下数小时的排查——而出问题几乎是必然的。好消息是:手边有一个格式化工具加一份 schema,修复往往只需要一次粘贴。