curl 命令实战
curl 是命令行下最强大的 HTTP 客户端,前后端开发者每天都离不开它。这一章按真实开发场景组织——GET、POST、上传、认证、Cookie、HTTPS、代理、性能——配可复制的命令。
1. curl 是什么
curl(client URL)是一个开源的命令行工具,支持 HTTP/HTTPS/FTP/SMTP 等十几种协议。Linux/macOS 系统自带(Windows 10+ 也内置了),所以是脚本里做 HTTP 调试最通用的选择。它的双胞胎是 libcurl,几乎所有编程语言都有基于它的库。
2. 基础用法
# 最简单的 GET
curl https://example.com/
# 加 -v 看请求和响应的完整报文 (调试神器)
curl -v https://example.com/
# 加 -i 只看响应头 (包含状态行)
curl -i https://example.com/
# 加 -o 保存到文件,-L 跟随重定向
curl -L -o page.html https://example.com/
# 加 -s 静默 (不显示进度条),-S 配合显示错误
curl -sS https://example.com/ -o /dev/null -w '%{http_code}\n'3. GET 请求与自定义头
# GET 带查询参数: 直接拼在 URL 里 (URL 加引号防 & 被 shell 解释)
curl 'https://api.example.com/users?role=admin&active=true'
# 加 User-Agent 头 (有些接口检查 UA)
curl -A 'Mozilla/5.0' https://example.com/
# 加自定义请求头
curl -H 'Accept: application/json' https://api.example.com/users
curl -H 'X-Request-Id: abc123' https://api.example.com/users几个高频参数:
-H / --header:加请求头。可多次使用。-A / --user-agent:设 User-Agent(等价于-H 'User-Agent: ...')。-L / --location:跟随 3xx 重定向。不加的话遇到 301/302 curl 直接返回响应而不跳。-o / --output:把响应 body 写到文件(默认打印到终端)。-O:用远程文件名保存。
4. POST/PUT/DELETE
# POST JSON
curl -X POST https://api.example.com/users \
-H 'Content-Type: application/json' \
-d '{"name":"Bob","email":"b@x.com"}'
# POST 表单 (-d 默认就是 application/x-www-form-urlencoded)
curl -X POST https://example.com/login \
-d 'username=alice' \
-d 'password=1234'
# POST 大段 JSON 用文件 (-d @filename)
curl -X POST https://api.example.com/users \
-H 'Content-Type: application/json' \
-d @payload.json
# -X 指定方法 (PUT/DELETE/PATCH)
curl -X DELETE https://api.example.com/users/42
curl -X PUT https://api.example.com/users/42 \
-H 'Content-Type: application/json' \
-d '{"name":"Bob II"}'-d / --data:发送数据。默认Content-Type: application/x-www-form-urlencoded,方法自动变 POST。-d @file:从文件读 body。-X / --request:强制指定方法(GET/POST/PUT/DELETE/PATCH)。注意:用-d时方法默认是 POST,-X不是必需的。
陷阱:在 URL 里写 & 必须给 URL 加引号,否则 shell 会把 & 当成后台执行符。
5. 文件上传与下载
# 上传单个文件 (multipart)
curl -X POST https://example.com/upload \
-F 'file=@/path/to/avatar.png'
# 上传文件 + 其他字段
curl -X POST https://example.com/upload \
-F 'title=我的头像' \
-F 'file=@/path/to/avatar.png'
# 指定文件的 Content-Type
curl -X POST https://example.com/upload \
-F 'file=@/path/to/data.csv;type=text/csv'
# 上传二进制 raw (-data-binary)
curl -X POST https://example.com/files \
-H 'Content-Type: application/octet-stream' \
--data-binary @/path/to/file.bin
# 下载文件 (等价 wget)
curl -O https://example.com/file.zip # 保留原文件名
curl -o renamed.zip https://example.com/file.zip # 改名-F / --form:multipart 上传。@前缀表示"这个值是文件路径"。--data-binary @file:原始二进制上传(不当成表单)。- 下载用
-O/-o,大文件加-C -支持断点续传。
6. 认证
# HTTP Basic Auth
curl -u alice:secret https://api.example.com/me
# 等价于 -H 'Authorization: Basic YWxpY2U6c2VjcmV0'
# Bearer Token (JWT)
curl -H 'Authorization: Bearer eyJhbGciOi...' https://api.example.com/me
# 用环境变量避免泄露 Token (注意花括号要转义或加引号)
TOKEN='eyJhbGciOi...'
curl -H "Authorization: Bearer ${TOKEN}" https://api.example.com/me
# 让 curl 自动处理 "用户名密码" -> Basic Auth:
curl --netrc-file ~/.netrc https://api.example.com/me
# ~/.netrc 内容: machine api.example.com login alice password secret用环境变量传 Token 时,双引号字符串才会展开变量,单引号不会。注意 shell 变量语法和 URL 模板字符串别混淆。
7. Cookie 处理
# 让 curl 保存服务器下发的 Cookie
curl -c cookies.txt https://example.com/login
# 后续请求带上 Cookie (实现"登录后再访问")
curl -b cookies.txt https://example.com/dashboard
# -c 和 -b 一起用: 保存 + 同时发送已有 Cookie
curl -b cookies.txt -c cookies.txt https://example.com/cart
# 手动指定 Cookie
curl -b 'sessionid=abc123; theme=dark' https://example.com/-c + -b 是模拟"登录 → 访问受保护页面"流程的标准做法。两个一起用,session 期间持续更新。
8. HTTPS 调试
# 跳过证书验证 (调试自签名证书时用,生产别加!)
curl -k https://self-signed.example.com/
# 指定 CA 证书
curl --cacert /path/to/ca.pem https://api.example.com/
# 指定客户端证书 (mTLS 双向认证)
curl --cert client.pem --key client.key https://mtls.example.com/
# 强制用 TLS 1.3
curl --tlsv1.3 https://example.com/
# 看证书链
curl -v https://example.com/ 2>&1 | grep -E 'subject|issuer'注意:-k 跳过证书验证只能用于调试,生产脚本里千万别用——这等于关掉了 HTTPS 最大的安全保障。最常见合法用法是测试自签名证书的内网服务。
9. 代理
# 走 HTTP 代理
curl -x http://proxy.example.com:8080 https://target.com/
# 走 SOCKS5 代理
curl --socks5 host:1080 https://target.com/
# 用 Charles/Fiddler 抓 HTTPS 包时,代理 + 信任它的 CA
curl -x http://127.0.0.1:8888 \
--cacert ~/Charles.crt \
https://target.com/
# 用环境变量让所有 curl 请求走代理
export https_proxy=http://127.0.0.1:7890
curl https://www.google.com/用 Charles / Fiddler / mitmproxy 抓 HTTPS 包时,标准流程:启动代理 → 信任 CA → curl 走代理 + 指定 CA。
10. 性能与超时
# 限时 (-m 总秒数, --connect-timeout 连接超时)
curl --connect-timeout 5 -m 10 https://example.com/
# 一次请求的耗时分解 (DNS、TCP、TLS、首字节、总时长)
curl -o /dev/null -s -w '
DNS: %{time_namelookup}s
TCP: %{time_connect}s
TLS: %{time_appconnect}s
FirstByte: %{time_starttransfer}s
Total: %{time_total}s
' https://example.com/
# 简单压测 (用 bash 循环,专业压测用 ab/wrk/k6)
for i in {1..100}; do
curl -s -o /dev/null -w '%{http_code}\n' https://api.example.com/health &
done
wait-w 的耗时分解特别适合排查慢请求——能立刻看出是 DNS 慢、TCP 慢、TLS 慢还是服务器响应慢。
11. -w 输出格式
# -w 输出变量 (常用)
%{http_code} # 状态码
%{time_total} # 总耗时
%{size_download} # 下载字节数
%{url_effective} # 实际 URL (跟随重定向后)
%{remote_ip} # 目标服务器 IP
%{ssl_verify_result} # 证书验证结果 (0 = OK)
# 实战: 只取状态码 (写脚本判断用)
code=$(curl -o /dev/null -s -w '%{http_code}' https://example.com/)
echo "状态码: ${code}"12. 常用组合速查
- 查看请求/响应报文:
curl -v URL - 看响应头:
curl -I URL或curl -i URL - 测试 POST JSON:
curl -X POST URL -H 'Content-Type: application/json' -d '{...}' - 只看状态码:
curl -o /dev/null -s -w '%{http_code}' URL - 下载文件:
curl -O URL - 跟重定向:
curl -L URL - 带 Cookie:
curl -b 'k=v' URL - 调试自签名证书:
curl -k URL
13. curl vs wget
- curl:默认输出到终端,更适合调试 API、写脚本、协议支持广(FTP/SMTP 都行)。
- wget:默认下载到文件,递归下载整个站点(
-r)、断点续传强。更适合批量下载。
现代开发 90% 用 curl——因为它能精确控制每一个 header 和方法。
14. 进阶工具
- httpie:curl 的现代化替代,命令更简洁(
http POST url name=alice),输出带语法高亮。 - Postman / Insomnia / Bruno:图形化 API 客户端,团队协作、保存请求集合。
- HTTPie + jq:管道处理 JSON 响应(
curl URL | jq '.users[0].name')。
小结
curl 三句话:看报文用 -v/-i,发数据用 -d/-F,调证书用 -k/--cacert。组合 -w + -o /dev/null 写脚本监控接口状态码是日常必备技巧。
← 上一篇 HTTPS 与 SSL/TLS
← 返回 HTTP 教程目录