← 全部文章

如何格式化 JSON:美化、校验与清理 JSON 文件

在 JavaScript 里用 JSON.stringify、在 Python 里用 json.dumps、在命令行里用 jq,或在浏览器里即时格式化 JSON。包括键排序、把 YAML 与 CSV 转成 JSON,以及真实的前后对比示例。

来自 API 或日志的原始 JSON 经常是一整行连成一片 —— 合法,但根本看不清。格式化 JSON(也叫「美化输出」或「beautify」)会加入一致的缩进与换行,让结构一目了然。本指南讲解如何在 JavaScript、Python、命令行以及浏览器中直接格式化一份 JSON 文件或字符串。

「格式化 JSON」是什么意思?

JSON 格式化器会把紧凑或缩进不一致的 JSON 字符串重写为:

  • 每个键值对独占一行
  • 嵌套的对象和数组按固定空格数缩进(通常是 2 或 4)
  • 不留尾随空白
// 格式化前(已最小化)
{"user":{"name":"Alice","age":30,"roles":["admin","editor"]}}

// 格式化后(2 空格缩进)
{
  "user": {
    "name": "Alice",
    "age": 30,
    "roles": [
      "admin",
      "editor"
    ]
  }
}

两种形式在语义上完全相同 —— 任何 JSON 解析器从中都会得到同一份数据结构。格式化纯粹是给人看的。

在 JavaScript 中格式化 JSON

JSON.stringify() 接收第二个参数(replacer)与第三个参数(缩进级别)。传 null 作为 replacer,并传 2 表示两空格缩进(完整 API 见 How to Stringify JSON):

const obj = { user: { name: "Alice", age: 30, roles: ["admin", "editor"] } };

// 紧凑(不格式化)
JSON.stringify(obj);
// '{"user":{"name":"Alice","age":30,"roles":["admin","editor"]}}'

// 2 空格缩进的美化输出
JSON.stringify(obj, null, 2);
// {
//   "user": {
//     "name": "Alice",
//     "age": 30,
//     "roles": [
//       "admin",
//       "editor"
//     ]
//   }
// }

// 4 空格缩进
JSON.stringify(obj, null, 4);

// Tab 缩进
JSON.stringify(obj, null, '\t');

格式化一个 JSON 字符串(不是对象)

如果你手上是一份已经合法但排版凌乱的 JSON 字符串,先解析再重新 stringify:

const raw = '{"name":"Alice","age":30}';
const formatted = JSON.stringify(JSON.parse(raw), null, 2);
console.log(formatted);

按字母排序键名

在格式化过程中给对象键排序,可以传入一个 replacer 函数,对每个遇到的对象排序其键:

function sortedStringify(obj, indent = 2) {
  return JSON.stringify(obj, (key, value) => {
    if (value && typeof value === 'object' && !Array.isArray(value)) {
      return Object.keys(value).sort().reduce((acc, k) => {
        acc[k] = value[k];
        return acc;
      }, {});
    }
    return value;
  }, indent);
}

在 Python 中格式化 JSON

Python 内建的 json 模块通过 indent 参数处理格式化:

import json

# 格式化 Python dict
data = {"user": {"name": "Alice", "age": 30, "roles": ["admin", "editor"]}}
formatted = json.dumps(data, indent=2)
print(formatted)

# 格式化一个 JSON 字符串
raw = '{"name":"Alice","age":30}'
formatted = json.dumps(json.loads(raw), indent=2)

# 按字母排序键名
formatted = json.dumps(data, indent=2, sort_keys=True)

# 格式化一份 JSON 文件
with open('input.json') as f:
    data = json.load(f)

with open('output.json', 'w') as f:
    json.dump(data, f, indent=2)

在命令行格式化 JSON 文件

用 jq(推荐)

jq 是命令行下事实上的 JSON 处理器。默认就会格式化 JSON:

# 美化一份 JSON 文件
jq . input.json

# 美化并保存到新文件
jq . input.json > output.json

# 格式化 curl 响应
curl -s https://api.example.com/users | jq .

# 按键排序
jq --sort-keys . input.json

用 Python(无需安装)

任何安装了 Python 的系统上,json.tool 模块都可以当作命令行格式化器:

# 格式化文件
python3 -m json.tool input.json

# 从标准输入读取并格式化
echo '{"name":"Alice","age":30}' | python3 -m json.tool

# 按键排序
python3 -m json.tool --sort-keys input.json

用 Node.js

node -e "const fs=require('fs'); const d=JSON.parse(fs.readFileSync('input.json')); console.log(JSON.stringify(d,null,2))"

如何把数据转换为 JSON 格式

「format to JSON」通常指把另一种格式(Python dict、CSV 文件、YAML 配置等)的数据序列化为合法的 JSON。

从 YAML 到 JSON

# Python
import yaml, json
with open('config.yaml') as f:
    data = yaml.safe_load(f)
print(json.dumps(data, indent=2))

或者在浏览器中使用 YAML 转 JSON 工具 —— 不需要写代码。关于如何在两种格式之间选择,参见 JSON vs YAML;关于 YAML 1.2 为什么是 JSON 的严格超集,参见 YAML 1.2 与 JSON 兼容性

从 CSV 到 JSON

import csv, json
with open('data.csv') as f:
    rows = list(csv.DictReader(f))
print(json.dumps(rows, indent=2))

从一个 JavaScript 对象

JavaScript 对象看着像 JSON 但并不是 —— 它们可以有未加引号的键、单引号字符串、尾随逗号和注释。把一个不合法的 JavaScript 对象字面值贴进 JSON Fix,就能自动把它转为合法 JSON。

在编辑器里格式化 JSON(Prettier、VS Code、pre-commit)

对日常工作来说,最有用的格式化时机是保存时 —— 这样未格式化的 JSON 永远不会进入 git 或 PR。

Prettier

# 安装
npm i -D prettier

# 原地格式化所有 .json(及源文件)
npx prettier --write "**/*.{json,jsonc}"

# 只做检查(适合 CI,有任何文件需要格式化就以非零状态退出)
npx prettier --check "**/*.json"

Prettier 开箱即用地支持 JSON 与 JSONC。一份只有两行的 .prettierrc,例如 { "tabWidth": 2 },通常就够了。

VS Code —— 保存时格式化

安装 Prettier 扩展,并在工作区 settings.json 中加入:

{
  "editor.formatOnSave": true,
  "[json]":   { "editor.defaultFormatter": "esbenp.prettier-vscode" },
  "[jsonc]":  { "editor.defaultFormatter": "esbenp.prettier-vscode" }
}

Pre-commit 钩子

要从根本上阻止未格式化的 JSON 被提交,请把 lint-stagedhusky 串起来:

// package.json
{
  "lint-staged": { "*.{json,jsonc}": "prettier --write" }
}

# 安装钩子
npx husky add .husky/pre-commit "npx lint-staged"

JSON 格式化示例:前后对比

// 未格式化 —— 合法但难读
{"orders":[{"id":1001,"customer":{"name":"Alice","email":"alice@example.com"},"items":[{"sku":"A1","qty":2,"price":9.99},{"sku":"B3","qty":1,"price":24.99}],"status":"shipped"},{"id":1002,"customer":{"name":"Bob","email":"bob@example.com"},"items":[{"sku":"C7","qty":3,"price":4.49}],"status":"pending"}]}

// 已格式化 —— 数据相同,可读
{
  "orders": [
    {
      "id": 1001,
      "customer": {
        "name": "Alice",
        "email": "alice@example.com"
      },
      "items": [
        { "sku": "A1", "qty": 2, "price": 9.99 },
        { "sku": "B3", "qty": 1, "price": 24.99 }
      ],
      "status": "shipped"
    },
    {
      "id": 1002,
      "customer": {
        "name": "Bob",
        "email": "bob@example.com"
      },
      "items": [
        { "sku": "C7", "qty": 3, "price": 4.49 }
      ],
      "status": "pending"
    }
  ]
}

常见问题

如何在 JavaScript 中格式化 JSON?

JSON.stringify(value, null, 2) —— 第三个参数设置缩进(2 空格、4 空格或 '\t' 表示 Tab)。要格式化已有的 JSON 字符串,先解析:JSON.stringify(JSON.parse(raw), null, 2)

如何在命令行美化 JSON?

jq . file.json(默认就会格式化),或者在没安装 jq 的环境里用 python3 -m json.tool file.json。加上 --sort-keys / --sort-keys 可按字母顺序排序键名。

格式化和最小化(minify)JSON 有什么区别?

格式化加入空白以提高可读性;最小化去除空白以减小体积。两者互为反向,都不改变数据。反向操作见 如何最小化 JSON

格式化 JSON 会改变数据吗?

不会。缩进和换行在 JSON 中是无意义的空白 —— 无论输入是紧凑的还是美化过的,每个解析器都会产出完全相同的数据结构。

在线格式化 JSON —— 无需配置

如果你现在就需要格式化一段 JSON 而不想写代码,JSON Fix 能即时格式化你的 JSON。贴入 JSON,点 Format,复制结果即可。它在格式化之前也会修复常见错误(尾随逗号、单引号、未加引号的键),所以哪怕你的 JSON 还不太合法也能用。