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 输出很难读
调试 API 时跑一下 curl,响应 JSON 通常是这样的:
curl -s https://api.example.com/users/1
{"id":1,"name":"Wang Lei","email":"wang@example.com","address":{"city":"Beijing","zip":"100000"},"roles":["admin","editor"]}
没有换行,没有缩进。嵌套越深,越没法用肉眼扫出结构。接下来介绍 4 种把这一长串文本变成可读 JSON 的方法。
方法 1: 用 jq 格式化
jq 是命令行处理 JSON 最流行的工具。
安装 jq
# macOS
brew install jq
# Ubuntu / Debian
sudo apt install jq
# Windows (Chocolatey 或 winget)
choco install jq
# 或者
winget install jqlang.jq
基本用法
把 curl 的输出通过管道传给 jq:
curl -s https://api.example.com/users/1 | jq .
{
"id": 1,
"name": "Wang Lei",
"email": "wang@example.com",
"address": {
"city": "Beijing",
"zip": "100000"
},
"roles": [
"admin",
"editor"
]
}
-s 参数让 curl 隐藏进度条,只把纯 JSON 传给 jq。
常用过滤
jq 不只是格式化,还能提取响应中的特定字段。
取某个键的值:
curl -s https://api.example.com/users/1 | jq '.name'
"Wang Lei"
嵌套对象用点号访问:
curl -s https://api.example.com/users/1 | jq '.address.city'
"Beijing"
从数组中取每个元素的某个字段,用 [] 语法:
curl -s https://api.example.com/users | jq '.[].name'
"Wang Lei"
"Li Na"
"Zhang Wei"
按条件过滤用 select:
curl -s https://api.example.com/users | jq '.[] | select(.roles[] == "admin")'
拿到数组响应后想直接生成 Markdown 表格 贴进 README 或 issue?用 jq 切出数组,再经 CSV 转成表格,一条管道就能搞定。
同时格式化响应头和 JSON(curl -i)
上面用 -s 的例子把响应体以外的信息全丢了。调 API 时经常需要同时看响应头和 JSON 体,这时就会想到 curl -i。但 curl -i | jq . 一定会报错,因为流最前面的 HTTP 头不是合法 JSON。
curl -is https://api.example.com/users/1 | jq .
# parse error: Invalid numeric literal at line 1, column 9
需要让响应头留在终端显示,同时只把 JSON 体传给 jq。
流分离:响应头走 stderr,响应体走 stdout
curl -D <文件> 把响应头写入指定目标。指向 /dev/stderr,响应头直接打印到终端,stdout 只剩纯 JSON 体供 jq 处理。
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": "Wang Lei",
...
}
响应头到了终端但不进管道,所以 jq 只收到合法 JSON。Windows PowerShell 没有 /dev/stderr,改用文件分离的方式(见下)。
文件分离:响应头和响应体各存一份
需要留档排查(比如保存失败请求)时,用 -D 和 -o 拆成两个文件:
curl -sSD head.txt -o body.json https://api.example.com/users/1
cat head.txt
jq . body.json
macOS、Linux、Windows 上行为一致。之后想 grep 响应头里的某个值,或者附到 bug 报告里,都方便。
注册为 shell 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 一条命令同时输出响应头和格式化 JSON。函数名取得明确,避免和 shell 历史里的其他命令撞名。
curl 7.82+ 的 --json 快捷参数(请求端)
格式化响应是读,发 JSON 是写。curl 7.82(2022 年 3 月)起支持 --json 参数,把 Content-Type: application/json、Accept: application/json、--data 三合一:
curl --json '{"name":"xiaomei"}' https://api.example.com/users
它本身不格式化响应,需要再管道给 jq 或本文其他方法。但请求端少写三个参数,配合 curl-json-format 处理响应,REST API 调试就变成干净的两步。
检查清单: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看响应头,如果content-type是text/html,大概率拿到的是错误页面、登录跳转或代理响应,不是 JSON。 - 确认 body 是 well-formed JSON。 JSON 文本必须是单一值:对象、数组、字符串、数字、或字面量
true/false/null(RFC 8259 第 2 节)。对象键必须用双引号,单引号和尾逗号都不合法。RFC 8259 第 8.1 节要求系统间交换的 JSON 使用 UTF-8 编码。 - 确认解析器无报错。
jq .或python3 -m json.tool如果返回 parse error 而不是格式化输出,说明 body 不是合法 JSON,跟 Content-Type 写的是什么无关。//和/* */注释不属于 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": "Wang Lei",
"email": "wang@example.com",
"address": {
"city": "Beijing",
"zip": "100000"
},
"roles": [
"admin",
"editor"
]
}
没有 jq 那种过滤能力,但纯格式化够用。只有 Python 2 的老环境用 python 代替 python3。
非 ASCII 字符默认被转义成 \uXXXX
json.tool 默认把非 ASCII 字符(中文、带重音的拉丁字母等)转成 \uXXXX 形式输出:
echo '{"city":"Bogotá","msg":"信息","p":"informação"}' | python3 -m json.tool
{
"city": "Bogot\u00e1",
"msg": "\u4fe1\u606f",
"p": "informa\u00e7\u00e3o"
}
这不是 bug,是 JSON 标准规定的行为。JSON 字符串允许用反斜杠 + u + 4 位十六进制数来表示基本多文种平面(BMP)中的任意字符(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 原始字符,加 -a(--ascii-output)才转成 \uXXXX(jq 手册在新标签页中打开)。
echo '{"city":"Bogotá","msg":"信息","p":"informação"}' | jq -a .
{
"city": "Bogot\u00e1",
"msg": "\u4fe1\u606f",
"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": "Wang Lei",
"email": "wang@example.com",
"address": {
"city": "Beijing",
"zip": "100000"
},
"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: Wang Lei
email: wang@example.com
address:
city: Beijing
zip: "100000"
roles:
- admin
- editor
API 响应需要立刻变成配置文件(YAML)或电子表格数据(CSV)时,一条管道搞定。
方法 4: 用浏览器格式化
FormatArc JSON 格式化器
不想在终端操作的话,把 curl 输出复制后贴到 FormatArc JSON 格式化器,点一下就行。
步骤很简单:
- 复制终端里的 curl 响应
- 打开 FormatArc JSON 格式化器
- 在左侧输入区粘贴
- 点击"Format"按钮
格式化结果可以一键复制,也可以直接在工具界面转成 YAML 或 CSV。
贴之前有一点要注意:curl 响应里经常带 Authorization 头、session token、用户数据等敏感信息。很多在线格式化工具会把粘贴内容上传到服务器。FormatArc 所有转换在浏览器本地完成,数据不出你的机器。
语法报错时怎么办
JSON 有语法错误就格式化不了。常见原因包括引号不配对、尾逗号、未转义的控制字符等。如果响应里包含 // 或 /* */ 注释导致 jq 或 json.tool 解析失败,那大概率是 JSONC 或 JSON5 格式,需要先去掉注释或用对应解析器。
4 种方法对比
| 方法 | 需要安装 | 过滤能力 | 适用场景 |
|---|---|---|---|
| jq | 需要 | 强 | 日常调 API 的后端 / DevOps 开发 |
| Python json.tool | 不需要(有 Python 即可) | 无 | 不想装额外工具时快速格式化 |
| formatarc CLI | npx 即跑 | 无(支持转换) | 格式化同时需要转 YAML/CSV |
| 浏览器(FormatArc) | 不需要 | 无 | 不想碰终端或需要可视化确认 |
日常用 jq,jq 没有的机器上 python3 -m json.tool --no-ensure-ascii 兜底,需要转其他格式或安全可视化时用 FormatArc。
常见问题
curl -i 管道给 jq 为什么报 parse error?
curl -i 把 HTTP 状态码和响应头一起写到 stdout。管道传给 jq 后,jq 试图把 HTTP/2 200 这一行当 JSON 解析,自然报错。用 curl -sSD /dev/stderr ... | jq . 把响应头转到 stderr 就解决了。
中文或特殊字符变成 \uXXXX 怎么办?
Python json.tool 默认转义非 ASCII 字符,加 --no-ensure-ascii 就输出原文(Python 3.9+)。jq 默认输出原文,如果你看到 \uXXXX,检查一下是不是误加了 -a 参数。
Windows 上怎么格式化 curl 的 JSON?
PowerShell 没有 /dev/stderr,用文件分离:curl.exe -sSD head.txt -o body.json <URL>,然后分别 type head.txt 和 jq . body.json。如果只需要 body,直接 curl.exe -s <URL> | jq . 就行。注意 PowerShell 默认的 curl 可能是 Invoke-WebRequest 的别名,显式写 curl.exe 更稳妥。
没有 jq 也没有 Python 怎么快速格式化?
Node.js 环境可以用:
node -e 'console.log(JSON.stringify(JSON.parse(require("fs").readFileSync(0,"utf8")),null,2))'
或者直接把 curl 输出贴到 FormatArc JSON 格式化器,浏览器里几秒搞定。
总结
curl 拿到的 JSON 响应,4 种格式化方式各有适用场景:jq 功能最强,curl -sSD /dev/stderr | jq . 能同时看响应头和格式化 body;Python json.tool 零安装成本;formatarc CLI 额外提供 YAML/CSV 转换;浏览器端用 FormatArc JSON 格式化器 最轻量。按你的环境和需求挑一个顺手的就好。

