TL;DR — 一行命令
如果環境有 jq,直接這樣就夠了:
curl -s https://api.example.com/users/1 | jq .
沒有 jq 就用 Python,大多數系統都預設安裝了:
curl -s https://api.example.com/users/1 | python3 -m json.tool
偏好瀏覽器的話,把 curl 的結果貼到 FormatArc JSON 格式化器 即可。不用安裝,首次載入後離線也能用。以下比較這 4 種方法,說明各種場景該選哪個。
為什麼 curl 的 JSON 回應不好讀
用 curl 呼叫 API 確認行為時,回傳的 JSON 通常是一整行:
curl -s https://api.example.com/users/1
{"id":1,"name":"Tanaka","email":"tanaka@example.com","address":{"city":"Tokyo","zip":"100-0001"},"roles":["admin","editor"]}
沒有換行也沒有縮排,巢狀結構越深越難用眼睛追蹤。下面介紹把這種輸出變成可讀 JSON 的 4 種方式。
方法 1:用 jq 格式化
JSON 格式化工具中 jq 的普及度最高。
安裝 jq
各作業系統的套件管理工具都有:
# macOS
brew install jq
# Ubuntu / Debian
sudo apt install jq
# Windows (Chocolatey)
choco install jq
基本用法
把 curl 的輸出用管線(|)傳給 jq:
curl -s https://api.example.com/users/1 | jq .
{
"id": 1,
"name": "Tanaka",
"email": "tanaka@example.com",
"address": {
"city": "Tokyo",
"zip": "100-0001"
},
"roles": [
"admin",
"editor"
]
}
-s 選項是隱藏 curl 的進度列,讓 stdout 只留下純 JSON 傳入 jq。
常用過濾器
jq 不只是格式化,還可以從回應中抽取出特定欄位。
取得單一鍵的值:
curl -s https://api.example.com/users/1 | jq '.name'
"Tanaka"
巢狀鍵用點號(.)存取:
curl -s https://api.example.com/users/1 | jq '.address.city'
"Tokyo"
從陣列的每個元素中提取特定欄位,用 []:
curl -s https://api.example.com/users | jq '.[].name'
"Tanaka"
"Suzuki"
"Sato"
用 select 做條件篩選:
curl -s https://api.example.com/users | jq '.[] | select(.roles[] == "admin")'
從檔案讀取 JSON
不需要每次都向伺服器發請求時,可以先把回應存成檔案,再用 jq 處理:
curl -s https://api.example.com/users/1 -o response.json
jq . response.json
-o 把回應寫入檔案,之後離線反覆查看或交給其他腳本處理都很方便。如果檔案很大,用 jq . response.json > formatted.json 輸出到另一個檔案。
傳送 JSON 請求(curl JSON POST)
向 API 送 JSON 時,傳統寫法需要三個旗標:
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":"alice"}' \
https://api.example.com/users
curl 7.82(2022 年 3 月發布)之後提供了 --json 簡寫,一個旗標就搞定:
curl --json '{"name":"alice"}' https://api.example.com/users
它同時設定 Content-Type: application/json、Accept: application/json 和 --data。注意 --json 只處理請求端,回應要格式化的話還是需要接上 jq 或其他方法:
curl --json '{"name":"alice"}' https://api.example.com/users | jq .
curl -i 同時顯示回應 header 和 JSON
前面 -s 的範例把回應 body 以外的東西全部丟掉了。除錯 API 時常需要同時看 header 和 body,這時候會想到 curl -i。但 curl -i | jq . 一定失敗,因為串流開頭的 header 區塊不是合法 JSON。
curl -is https://api.example.com/users/1 | jq .
# parse error: Invalid numeric literal at line 1, column 9
需要讓 header 顯示在終端機上,同時只把 JSON body 傳給 jq。
串流分離:header 走 stderr,body 走 stdout
curl -D <檔案> 把回應 header 寫入指定的目標。指定 /dev/stderr 的話,header 印到終端機,stdout 只留下給 jq 處理的純 JSON body:
curl -sSD /dev/stderr https://api.example.com/users/1 | jq .
HTTP/2 200
content-type: application/json
cache-control: no-store
date: Mon, 19 May 2026 09:30:00 GMT
{
"id": 1,
"name": "Tanaka",
...
}
header 到終端機但不進管線,所以 jq 收到的是合法 JSON。Windows PowerShell 沒有 /dev/stderr 這個裝置檔,改用下面的檔案分離方式。
檔案分離:header 和 body 存成不同檔案
需要保留兩者做後續分析時(比如存下失敗請求的紀錄),用 -D 和 -o 分成兩個檔案:
curl -sSD head.txt -o body.json https://api.example.com/users/1
cat head.txt
jq . body.json
macOS、Linux、Windows 任何 shell 都能這樣做。之後要用 grep 找 header 中的特定值,或附上 bug 報告都方便。
設成永久 alias
多數時候一條短命令就夠了。加到 ~/.bashrc 或 ~/.zshrc:
alias curl-json='curl -sSD /dev/stderr'
curl-json-format() { curl-json "$@" | jq .; }
之後 curl-json-format https://api.example.com/users/1 一條命令就能同時看 header 和格式化 JSON。
檢查清單:curl 的回應真的是合法 JSON 嗎
把回應傳給 jq 或 json.tool 之前,確認兩件事:伺服器有沒有把 body 宣告為 JSON、body 本身是否良構。JSON 資料交換格式由 RFC 8259 (STD 90)在新分頁中開啟 定義,語法摘要見 json.org在新分頁中開啟。
- 確認 Content-Type 是
application/json。RFC 8259 將application/json註冊為 JSON 的媒體型別。用curl -i或上面的curl -sSD /dev/stderr模式看回應 header,如果content-type是text/html,很可能是錯誤頁面、登入重定向或 proxy 回應混進來了。 - 確認 body 是良構 JSON。JSON 文字必須是單一值——物件、陣列、字串、數字,或
true/false/null(RFC 8259 第 2 節)。物件的鍵必須是雙引號字串,單引號不行,尾端逗號也不合法。RFC 8259 第 8.1 節要求跨系統交換的 JSON 必須用 UTF-8 編碼。 - 確認解析器不報錯。
jq .或python3 -m json.tool如果回傳 parse error 而不是格式化結果,不管 Content-Type 寫什麼,那個 body 就不是合法 JSON。//或/* */註解不屬於 JSON 的一部分,包含註解的是 JSONC 或 JSON5。
方法 2:用 Python json.tool 格式化
環境有 Python 的話不用裝額外的東西,標準函式庫的 json.tool 模組直接可用。
curl -s https://api.example.com/users/1 | python3 -m json.tool
{
"id": 1,
"name": "Tanaka",
"email": "tanaka@example.com",
"address": {
"city": "Tokyo",
"zip": "100-0001"
},
"roles": [
"admin",
"editor"
]
}
沒有 jq 那種過濾功能,但純格式化用途完全足夠。只有 Python 2 的環境改用 python 命令即可。
非 ASCII 字元預設會被逸出成 \uXXXX
json.tool 預設會把中文、日文、帶調號的拉丁字母等非 ASCII 字元轉成 \uXXXX 形式:
echo '{"city":"Bogotá","msg":"情報","p":"informação"}' | python3 -m json.tool
{
"city": "Bogot\u00e1",
"msg": "\u60c5\u5831",
"p": "informa\u00e7\u00e3o"
}
這不是 bug,是 JSON 標準的規定行為。JSON 字串可以用反斜線 + u + 四位十六進位數來表示 Basic Multilingual Plane 中的字元(RFC 8259 第 7 節在新分頁中開啟)。但要在終端機直接讀中文或日文的日誌時,可讀性就很差。
加 --no-ensure-ascii 就能保留原始字元。這個旗標是 Python 3.9 加入的(Python 官方文件在新分頁中開啟):
echo '{"city":"Bogotá","msg":"情報","p":"informação"}' | python3 -m json.tool --no-ensure-ascii
{
"city": "Bogotá",
"msg": "情報",
"p": "informação"
}
jq 的行為剛好相反。預設直接以 UTF-8 原樣輸出非 ASCII 字元,加 -a(--ascii-output)才會逸出成 \uXXXX(jq 手冊在新分頁中開啟):
echo '{"city":"Bogotá","msg":"情報","p":"informação"}' | jq -a .
{
"city": "Bogot\u00e1",
"msg": "\u60c5\u5831",
"p": "informa\u00e7\u00e3o"
}
實測結果(Python 3.14.6 / jq 1.7.1)存放於倉庫的 scripts/benchmarks/json-tool-non-ascii/ 目錄。
方法 3:用 formatarc CLI 格式化
安裝與用法
用 Node.js 環境的話,透過 npx 免安裝直接執行:
curl -s https://api.example.com/users/1 | npx formatarc json-format
{
"id": 1,
"name": "Tanaka",
"email": "tanaka@example.com",
"address": {
"city": "Tokyo",
"zip": "100-0001"
},
"roles": [
"admin",
"editor"
]
}
如果經常使用,可以全域安裝,省去 npx 的啟動時間:
npm install -g formatarc
curl -s https://api.example.com/users/1 | formatarc json-format
管線中轉 YAML / CSV
formatarc 除了 JSON 格式化,還能在同一條管線中轉成 YAML 或 CSV:
curl -s https://api.example.com/users/1 | npx formatarc json-to-yaml
id: 1
name: Tanaka
email: tanaka@example.com
address:
city: Tokyo
zip: "100-0001"
roles:
- admin
- editor
拿到 API 回應後要直接寫成設定檔(YAML)或試算表資料(CSV)時,一條管線搞定很實用。
方法 4:在瀏覽器中格式化
使用 FormatArc JSON 格式化器
不想用命令行的話,把 curl 的輸出複製後貼到 FormatArc JSON 格式化器 就能一鍵格式化。
步驟很簡單:
- 複製終端機中的 curl 回應
- 開啟 FormatArc JSON 格式化器
- 貼到左側輸入區
- 按「Format」按鈕
格式化結果可以直接複製,也可以在工具畫面上轉成 YAML 或 CSV。
用線上工具前有一件事要注意:curl 的回應常包含 Authorization token、session 金鑰、使用者資料等敏感資訊。許多線上格式化工具會把貼上的內容傳到伺服器。FormatArc 的所有轉換都在瀏覽器內完成,資料不會傳到外部。
遇到語法錯誤時
JSON 有語法錯誤的話格式化會失敗。常見原因包括引號未閉合、尾端逗號、未逸出的控制字元等。如果 API 回應包含 // 或 /* */ 註解導致 jq 或 json.tool 解析失敗,那可能是 JSONC 或 JSON5 格式,需要先用對應的解析器處理。
四種方法比較
| 方法 | 是否需要安裝 | 過濾功能 | 適用場景 |
|---|---|---|---|
| jq | 需要 | 強大 | 每天跟 API 打交道的開發者 |
| Python json.tool | 不需要(需 Python) | 無 | 不想裝工具、快速格式化 |
| formatarc CLI | npx 即可執行 | 無(可轉格式) | 需要同時轉 YAML / CSV |
| 瀏覽器(FormatArc) | 不需要 | 無 | 不習慣命令行或只需看一次 |
日常用 jq,需要轉 YAML 或 CSV 時加 formatarc CLI,偶爾用瀏覽器視覺化確認,是最實際的組合。
常見問題
curl -i 接 jq 為什麼報 parse error?
curl -i 會把 HTTP 狀態碼和 header 區塊放在 stdout 的最前面。用管線傳給 jq 時,jq 嘗試把 HTTP/2 200 當 JSON 解析,所以報 parse error: Invalid numeric literal。要用 curl -sSD /dev/stderr ... | jq . 把 header 導到 stderr 才行。
中文或日文變成 \uXXXX 怎麼辦?
Python json.tool 預設會逸出非 ASCII 字元。加 --no-ensure-ascii 旗標(Python 3.9 以上)就能保留原始字元。jq 預設就是直接輸出 UTF-8,如果看到 \uXXXX 就是誤加了 -a 旗標。
Windows PowerShell 中怎麼做?
PowerShell 沒有 /dev/stderr 裝置檔。用 curl.exe -sSD head.txt -o body.json <URL> 把 header 和 body 存成檔案,再分別查看。或者只需要 body 的話直接 curl.exe -s <URL> | jq .。另外注意 PowerShell 的 curl 可能是 Invoke-WebRequest 的別名,要明確寫 curl.exe。
沒有 jq 也裝不了新套件的時候怎麼辦?
遠端 Linux 伺服器沒有 package manager 權限時,用 Python 標準模組 python3 -m json.tool --no-ensure-ascii 最省事。如果有 Node.js,也可以用:
curl -s https://api.example.com/users/1 | node -e 'console.log(JSON.stringify(JSON.parse(require("fs").readFileSync(0,"utf-8")),null,2))'
curl 回應中有註解(//)導致解析失敗?
RFC 8259 標準 JSON 不支援註解。回應中有註解的話是 JSONC 或 JSON5 格式,需要先用支援該格式的解析器去除註解再交給 jq 或 json.tool 處理。
小結
curl 取得的 JSON 格式化有 4 種路徑:jq 功能最完整且能過濾欄位,curl -sSD /dev/stderr | jq . 的模式可以同時看 header 又不影響解析;Python json.tool 免安裝、加 --no-ensure-ascii 就能正確顯示中文;formatarc CLI 在管線中多提供 YAML / CSV 轉換;需要視覺化確認或不想碰命令行的話,FormatArc JSON 格式化器在瀏覽器中完成所有處理,資料不離開你的機器。

