← 全部文章

如何格式化 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 還不太合法也能用。