联调时最怕两件事:一是 Postman 装不上(内网机器、公司策略限制),二是「浏览器能通、脚本不通」说不清差在哪。curl 到处都是,但参数太多记不住。这篇只挑真正高频的 8 个参数,配两个实战排查过程。

一、看链路:-v 和 -I

# 完整请求与响应过程(含 DNS、TCP、TLS、请求头、响应头)
curl -v https://api.example.com/users

# 只要响应头,不发 body
curl -I https://api.example.com/users

-v 的输出里,> 开头是 curl 发出去的,< 开头是服务端返回的。排查「请求头没带上」这类问题,只看 -v 就知道,不需要抓包。

二、认证与请求头:-H

# Bearer Token
curl -H "Authorization: Bearer <token>" https://api.example.com/users

# 自定义追踪头
curl -H "X-Trace-Id: abc123" https://api.example.com/users

# Basic 认证(等价于 -H "Authorization: Basic base64(user:pass)")
curl -u user:password https://api.example.com/users

顺手提醒:Token 里如果带 . 分隔的三段,可以直接用 JWT 解析工具 看过期时间和 payload,比在日志里猜快。

三、发 JSON:-X -H -d 三件套

curl -X POST https://api.example.com/users 
  -H "Content-Type: application/json" 
  -d '{"name":"tom","age":18}'

三个要素缺一不可:-X POST 指定方法,-H 指定内容类型,-d 才是数据。JSON 必须用单引号包住整体,否则 shell 会把里面的双引号吃掉。只写 -d 不带 Content-Type,服务端会按表单解析,字段全部收不到 —— 这是「接口收到 null」的第一大原因。

JSON 比较长的时候,别硬塞命令行,写到文件里:

curl -X POST https://api.example.com/users 
  -H "Content-Type: application/json" 
  --data-binary @body.json

四、中文参数:-G --data-urlencode

直接拼在 URL 上的中文和空格会出问题,让 curl 帮你编码:

curl -G https://api.example.com/search 
  --data-urlencode "q=中文 空格" 
  --data-urlencode "page=1"

-G 表示把 --data-urlencode 的内容拼到查询串而不是 body。手写 URL 编码容易漏掉空格变 + 还是 %20 的问题,这个参数直接规避。

五、上传文件:-F

curl -F "file=@/path/to/report.pdf" https://api.example.com/upload

# 同时带普通字段
curl -F "file=@report.pdf" -F "bizType=invoice" https://api.example.com/upload

@ 后面是本地文件路径,-F 会自动设置 multipart/form-data 和 boundary。注意 -F 和 -d 不能混用,混用会让整个请求体编码错乱。

六、重定向与证书:-L -k

# 跟随 301/302
curl -L https://example.com

# 忽略 HTTPS 证书校验(仅自签测试环境)
curl -k https://10.0.0.1/api

-k 会掩盖中间人风险,只在自签证书的内网测试用。生产环境如果必须加,说明证书链没配全,该修的是证书。

七、超时:两段分开设

curl --connect-timeout 5 --max-time 20 https://api.example.com/slow

--connect-timeout 管建连阶段,--max-time 管整个请求。只设 --max-time 的问题在于:DNS 卡住时它也在计时,但你分不清是「连不上」还是「后端慢」。

八、复用会话:-b 和 -c

# 带上已有 Cookie
curl -b "session=abc123" https://api.example.com/me

# 把响应里的 Set-Cookie 存下来,下次直接用
curl -c cookies.txt -X POST https://api.example.com/login -d "user=tom&pass=123"
curl -b cookies.txt https://api.example.com/me

排查「登录后接口还是 401」,用 -c + -b 两步走,能立刻验证是不是 Cookie 没带上。

实战一:接口一直返回 401

curl -v -H "Authorization: Bearer <token>" https://api.example.com/me

看 -v 输出里 > 那几行:

  • 如果没有 Authorization 行 → Token 变量没展开,检查 shell 引号
  • 如果有但服务端返回 401 → Token 过期或签名不对,用 JWT 解析工具 看 exp
  • 如果 Token 明显正确仍 401 → 检查是不是有多余空格、或者前缀写成了 Bearer: (多了冒号)

实战二:POST 成功但字段全空

九成是 Content-Type 没设,或设成了 text/plain。用 -v 确认实际发出去的请求头,再用 JSON 格式化工具 检查 body 里字段名的大小写和下划线 —— userName 和 user_name 在有些框架里不会自动映射。

常见坑

  • PowerShell 吞引号:Windows PowerShell 下 -d {"name":"tom"} 的双引号会被吃掉,改用 --data-binary @body.json 读文件最稳。
  • -k 掩盖证书问题:本地通了、线上不通,往往是证书链缺中间证书,不是 curl 的问题。
  • -L 丢失 POST:301/302 重定向时 curl 默认把方法改成 GET,需要 --post301 --post302 保留 body。
  • 长命令换行:Windows cmd 用 ^ 续行,PowerShell 用反引号 `,Linux 用 `` —— 混用会导致参数被截断。

相关速查