cURL
cURL(Client URL)是一个广泛使用的命令行工具和库,用于传输数据,支持多种协议,包括 HTTP、HTTPS、FTP、SFTP 等。cURL 非常强大,它允许你在命令行中执行各种数据传输操作,如下载和上传文件,以及与服务器交互。

查看更多相关内容
cURL 的 -X 参数有什么作用?PUT、DELETE、PATCH 请求如何使用?在 cURL 中,`-X` 或 `--request` 参数用于**指定 HTTP 请求方法**。虽然 cURL 会根据其他参数自动推断方法,但显式指定方法可以让请求更加明确和可控。
### -X 参数基础
```bash
# 基本语法
curl -X METHOD URL
# 常见用法
curl -X GET https://api.example.com/users
curl -X POST https://api.example.com/users
curl -X PUT https://api.example.com/users/1
curl -X DELETE https://api.example.com/users/1
curl -X PATCH https://api.example.com/users/1
```
### HTTP 方法详解
#### GET 请求
```bash
# GET 请求(默认,通常不需要 -X GET)
curl https://api.example.com/users
# 显式指定 GET
curl -X GET https://api.example.com/users
# 带查询参数的 GET
curl -X GET "https://api.example.com/users?page=1&limit=10"
# 带请求头的 GET
curl -X GET \
-H "Authorization: Bearer token123" \
https://api.example.com/users
```
#### POST 请求
```bash
# POST 请求(使用 -d 时自动使用 POST)
curl -X POST \
-H "Content-Type: application/json" \
-d '{"name":"张三"}' \
https://api.example.com/users
# 表单数据 POST
curl -X POST \
-d "username=admin&password=123456" \
https://api.example.com/login
# 文件上传 POST
curl -X POST \
-F "file=@document.pdf" \
https://api.example.com/upload
```
#### PUT 请求
PUT 用于**完整更新**资源,通常需要提供资源的全部字段。
```bash
# 基本 PUT 请求
curl -X PUT \
-H "Content-Type: application/json" \
-H "Authorization: Bearer token123" \
-d '{"id":1,"name":"张三","email":"zhangsan@example.com","age":25}' \
https://api.example.com/users/1
# PUT 更新文件内容
curl -X PUT \
-H "Content-Type: application/octet-stream" \
--data-binary @updated-file.txt \
https://api.example.com/files/document.txt
# PUT 上传文件(REST API 风格)
curl -X PUT \
-T local-file.pdf \
https://api.example.com/documents/123
```
#### DELETE 请求
DELETE 用于**删除**资源。
```bash
# 基本 DELETE 请求
curl -X DELETE \
-H "Authorization: Bearer token123" \
https://api.example.com/users/1
# DELETE 带请求体(某些 API 需要)
curl -X DELETE \
-H "Content-Type: application/json" \
-H "Authorization: Bearer token123" \
-d '{"reason":"inactive user"}' \
https://api.example.com/users/1
# 批量删除
curl -X DELETE \
-H "Content-Type: application/json" \
-d '{"ids":[1,2,3]}' \
https://api.example.com/users/batch
```
#### PATCH 请求
PATCH 用于**部分更新**资源,只需提供要修改的字段。
```bash
# 基本 PATCH 请求
curl -X PATCH \
-H "Content-Type: application/json" \
-H "Authorization: Bearer token123" \
-d '{"email":"newemail@example.com"}' \
https://api.example.com/users/1
# JSON Patch 格式 (RFC 6902)
curl -X PATCH \
-H "Content-Type: application/json-patch+json" \
-d '[{"op":"replace","path":"/email","value":"new@example.com"}]' \
https://api.example.com/users/1
# Merge Patch 格式 (RFC 7386)
curl -X PATCH \
-H "Content-Type: application/merge-patch+json" \
-d '{"email":"new@example.com","settings":{"theme":"dark"}}' \
https://api.example.com/users/1
```
### HTTP 方法对比
| 方法 | 用途 | 幂等性 | 安全性 | 典型场景 |
| ------- | ------- | --- | --- | ------- |
| GET | 获取资源 | ✅ | ✅ | 查询数据 |
| POST | 创建资源 | ❌ | ❌ | 提交表单、创建 |
| PUT | 完整更新 | ✅ | ❌ | 替换资源 |
| PATCH | 部分更新 | ❌ | ❌ | 修改部分字段 |
| DELETE | 删除资源 | ✅ | ❌ | 删除操作 |
| HEAD | 获取元数据 | ✅ | ✅ | 检查资源存在 |
| OPTIONS | 获取支持的方法 | ✅ | ✅ | CORS 预检 |
### 其他 HTTP 方法
```bash
# HEAD 请求(仅获取响应头)
curl -X HEAD https://api.example.com/users/1
# 或使用 -I
curl -I https://api.example.com/users/1
# OPTIONS 请求(CORS 预检)
curl -X OPTIONS \
-H "Origin: https://example.com" \
-H "Access-Control-Request-Method: POST" \
https://api.example.com/users
# TRACE 请求(调试,通常被禁用)
curl -X TRACE https://api.example.com/debug
# CONNECT 请求(建立隧道)
curl -X CONNECT http://proxy.example.com:8080
```
### RESTful API 完整示例
```bash
#!/bin/bash
# RESTful API 完整操作示例
API_BASE="https://api.example.com/v1"
TOKEN="your_bearer_token"
# 1. 创建资源 (POST)
echo "Creating user..."
CREATE_RESPONSE=$(curl -s -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"name":"张三","email":"zhangsan@example.com"}' \
"$API_BASE/users")
USER_ID=$(echo $CREATE_RESPONSE | jq -r '.id')
echo "Created user ID: $USER_ID"
# 2. 获取资源 (GET)
echo "Getting user..."
curl -s -X GET \
-H "Authorization: Bearer $TOKEN" \
"$API_BASE/users/$USER_ID" | jq
# 3. 完整更新 (PUT)
echo "Updating user (PUT)..."
curl -s -X PUT \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d "{\"id\":$USER_ID,\"name\":\"张三\",\"email\":\"updated@example.com\",\"age\":26}" \
"$API_BASE/users/$USER_ID" | jq
# 4. 部分更新 (PATCH)
echo "Updating user (PATCH)..."
curl -s -X PATCH \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"age":27}' \
"$API_BASE/users/$USER_ID" | jq
# 5. 删除资源 (DELETE)
echo "Deleting user..."
curl -s -X DELETE \
-H "Authorization: Bearer $TOKEN" \
"$API_BASE/users/$USER_ID"
echo "User deleted"
```
### 注意事项
1. **自动推断方法**:
* 使用 `-d` 时,cURL 默认使用 POST
* 使用 `-T` 时,cURL 默认使用 PUT
* 显式使用 `-X` 可以覆盖默认行为
2. **幂等性考虑**:
* GET、PUT、DELETE 应该是幂等的
* POST、PATCH 通常不是幂等的
3. **Content-Type**:
* 发送数据时必须设置正确的 Content-Type
* JSON: `application/json`
* 表单: `application/x-www-form-urlencoded`
* 文件: `multipart/form-data`
4. **安全性**:
* GET 不应该有副作用
* DELETE 操作应该谨慎
* 敏感操作需要认证
服务端 · 3月7日 19:41
如何使用 cURL 发送 GET 和 POST 请求?在 cURL 中,**GET 和 POST 请求**是最常用的两种 HTTP 方法,它们的使用场景和参数配置有所不同。
### GET 请求
GET 请求用于获取数据,参数通常附加在 URL 中。
```bash
# 基础 GET 请求
curl https://api.example.com/users
# 带查询参数
curl "https://api.example.com/users?page=1&limit=10"
# 带请求头
curl -H "Authorization: Bearer token123" \
-H "Accept: application/json" \
https://api.example.com/users
# 显示响应头信息
curl -i https://api.example.com/users
# 仅显示响应头
curl -I https://api.example.com/users
```
### POST 请求
POST 请求用于提交数据,需要使用 `-X POST` 指定方法,`-d` 传递数据。
```bash
# 发送 JSON 数据
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name":"张三","email":"zhangsan@example.com"}'
# 发送表单数据
curl -X POST https://api.example.com/login \
-d "username=admin&password=123456"
# 从文件读取数据
curl -X POST https://api.example.com/upload \
-H "Content-Type: application/json" \
-d @data.json
# 上传文件
curl -X POST https://api.example.com/upload \
-F "file=@/path/to/file.pdf"
```
### 关键区别
| 特性 | GET | POST |
| ---- | ---------- | ---- |
| 数据位置 | URL 参数 | 请求体 |
| 数据大小 | 受 URL 长度限制 | 无限制 |
| 安全性 | 参数可见 | 相对安全 |
| 缓存 | 可被缓存 | 不缓存 |
| 幂等性 | 幂等 | 非幂等 |
### 常用参数说明
* `-X` 或 `--request`:指定 HTTP 方法
* `-H` 或 `--header`:添加请求头
* `-d` 或 `--data`:发送数据
* `-F` 或 `--form`:上传表单/文件
* `-i`:显示响应头和内容
* `-I`:仅显示响应头
服务端 · 3月7日 19:41
cURL 如何处理 HTTP 认证(Basic Auth、Bearer Token、OAuth)?在 cURL 中,**认证(Authentication)** 是访问受保护资源的关键步骤。cURL 支持多种认证方式,包括 Basic Auth、Bearer Token、OAuth 等。
### Basic Authentication
Basic Auth 是最简单的认证方式,将用户名和密码进行 Base64 编码后发送。
```bash
# 方式一:使用 -u 参数
curl -u "username:password" https://api.example.com/protected
# 方式二:手动编码(不推荐)
curl -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" \
https://api.example.com/protected
# 仅提供用户名,cURL 会提示输入密码
curl -u "username" https://api.example.com/protected
# 从环境变量读取密码
curl -u "username:$PASSWORD" https://api.example.com/protected
```
### Bearer Token 认证
Bearer Token 是现代 API 最常用的认证方式。
```bash
# 使用 Bearer Token
curl -H "Authorization: Bearer your_access_token_here" \
https://api.example.com/protected
# 结合其他参数
curl -X POST \
-H "Authorization: Bearer token123" \
-H "Content-Type: application/json" \
-d '{"name":"test"}' \
https://api.example.com/resource
# 从文件读取 Token
TOKEN=$(cat token.txt)
curl -H "Authorization: Bearer $TOKEN" \
https://api.example.com/protected
```
### API Key 认证
API Key 通常通过查询参数或请求头传递。
```bash
# 查询参数方式
curl "https://api.example.com/data?api_key=your_api_key_here"
# 请求头方式
curl -H "X-API-Key: your_api_key_here" \
https://api.example.com/data
# 自定义请求头名称
curl -H "ApiKey: your_api_key_here" \
https://api.example.com/data
```
### OAuth 2.0 认证
OAuth 2.0 是复杂的认证流程,通常包含多个步骤。
```bash
# 步骤 1:获取 Access Token
curl -X POST https://auth.example.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=your_client_id" \
-d "client_secret=your_client_secret"
# 步骤 2:使用 Access Token 访问资源
curl -H "Authorization: Bearer access_token_from_step1" \
https://api.example.com/protected
# OAuth 密码模式
curl -X POST https://auth.example.com/oauth/token \
-d "grant_type=password" \
-d "username=user@example.com" \
-d "password=user_password" \
-d "client_id=your_client_id"
```
### Digest 认证
Digest 认证比 Basic Auth 更安全。
```bash
# 使用 --digest 参数
curl --digest -u "username:password" \
https://api.example.com/protected
```
### 认证方式对比
| 认证方式 | 安全性 | 使用场景 | cURL 参数 |
| ------------ | ---------- | ------ | ---------------------------- |
| Basic Auth | 低(需 HTTPS) | 简单场景 | `-u` |
| Bearer Token | 中 | API 调用 | `-H "Authorization: Bearer"` |
| API Key | 中 | 开放 API | `-H "X-API-Key"` 或查询参数 |
| OAuth 2.0 | 高 | 第三方授权 | 多步骤流程 |
| Digest | 高 | 内部系统 | `--digest` |
### 实战示例
```bash
# GitHub API 认证
curl -H "Authorization: Bearer ghp_xxxx" \
https://api.github.com/user
# AWS API(需要签名)
curl -X GET "https://s3.amazonaws.com/bucket/file" \
-H "Authorization: AWS4-HMAC-SHA256 ..."
# 带认证的完整 API 调用
curl -X POST https://api.example.com/orders \
-H "Authorization: Bearer token123" \
-H "Content-Type: application/json" \
-H "X-Request-ID: $(uuidgen)" \
-d '{"product_id": 123, "quantity": 2}'
```
### 安全最佳实践
1. **使用环境变量**:不要在命令行中硬编码密码
2. **HTTPS 必须**:认证信息必须通过加密通道传输
3. **Token 过期**:定期刷新 Access Token
4. **权限最小化**:只申请必要的权限范围
5. **日志安全**:避免在日志中记录敏感信息
服务端 · 3月7日 19:39
cURL 性能优化和最佳实践有哪些?**性能优化和最佳实践**能显著提升 cURL 的使用效率和可靠性。掌握这些技巧对于生产环境至关重要。
### 超时设置
```bash
# 连接超时(秒)
curl --connect-timeout 10 https://api.example.com
# 最大传输时间(秒)
curl --max-time 30 https://api.example.com
# 组合使用
curl --connect-timeout 5 --max-time 30 https://api.example.com
# 毫秒级超时(7.68.0+)
curl --connect-timeout 3.5 --max-time 10.5 https://api.example.com
```
### 重试机制
```bash
# 自动重试
curl --retry 3 https://api.example.com
# 重试延迟(秒)
curl --retry 3 --retry-delay 2 https://api.example.com
# 指数退避重试
curl --retry 3 --retry-delay 1 --retry-max-time 10 https://api.example.com
# 特定错误码重试
curl --retry 5 --retry-connrefused https://api.example.com
```
### 连接复用
```bash
# 保持连接(HTTP Keep-Alive)
curl --keepalive-time 60 https://api.example.com
# 限制连接数
curl --limit-rate 100K https://api.example.com
# 并发请求(使用 xargs)
cat urls.txt | xargs -P 5 -I {} curl -s {} -o /dev/null
```
### 压缩传输
```bash
# 请求压缩响应
curl --compressed https://api.example.com
# 手动指定压缩
curl -H "Accept-Encoding: gzip, deflate" https://api.example.com
```
### 性能分析
```bash
# 详细性能指标
curl -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nSSL: %{time_appconnect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\nSize: %{size_download}B\nSpeed: %{speed_download}B/s\n" \
-o /dev/null -s https://api.example.com
# 保存性能报告
curl -w "@perf-format.txt" -o /dev/null -s https://api.example.com > perf.log
```
### 批量处理优化
```bash
# 批量下载(并行)
#!/bin/bash
urls=(
"https://api.example.com/users"
"https://api.example.com/products"
"https://api.example.com/orders"
)
for url in "${urls[@]}"; do
curl -s "$url" -o "$(basename $url).json" &
done
wait
# 使用 GNU Parallel
cat urls.txt | parallel -j 4 curl -s {} -o {/}.json
# 连接池复用
curl -K - <<EOF
url = "https://api.example.com/users"
output = "users.json"
url = "https://api.example.com/products"
output = "products.json"
EOF
```
### 内存和资源优化
```bash
# 限制下载速度
curl --limit-rate 1M https://example.com/large-file.zip -O
# 分块下载
curl -r 0-1024000 https://example.com/large-file.zip -o part1.zip
curl -r 1024001-2048000 https://example.com/large-file.zip -o part2.zip
# 断点续传
curl -C - -O https://example.com/large-file.zip
# 流式处理(不保存到内存)
curl -s https://api.example.com/stream | jq '.[] | .name'
```
### 最佳实践清单
#### 1. 安全性
```bash
# 始终验证 SSL 证书
curl https://api.example.com
# 使用最新 TLS 版本
curl --tlsv1.2 --tls-max tls1.3 https://api.example.com
# 不在命令行暴露密码
curl -u "username" https://api.example.com
# 让 cURL 提示输入密码
# 使用环境变量
curl -H "Authorization: Bearer $API_TOKEN" https://api.example.com
```
#### 2. 可靠性
```bash
# 设置合理的超时
curl --connect-timeout 10 --max-time 60 https://api.example.com
# 启用重试机制
curl --retry 3 --retry-delay 2 --retry-max-time 30 https://api.example.com
# 错误处理
curl -f https://api.example.com || echo "Request failed"
# 检查退出码
curl -s https://api.example.com
if [ $? -ne 0 ]; then
echo "Error occurred"
fi
```
#### 3. 可维护性
```bash
# 使用配置文件
# ~/.curlrc
verbose
connect-timeout = 10
max-time = 60
retry = 3
# 使用变量和函数
#!/bin/bash
API_BASE="https://api.example.com/v1"
TOKEN="your_token"
api_call() {
curl -s -H "Authorization: Bearer $TOKEN" "$API_BASE/$1"
}
api_call "users"
api_call "products"
```
#### 4. 日志和监控
```bash
# 记录请求日志
curl -v https://api.example.com 2>&1 | tee request.log
# 结构化日志
curl -w "$(date '+%Y-%m-%d %H:%M:%S') | URL: %{url_effective} | Status: %{http_code} | Time: %{time_total}s\n" \
-o /dev/null -s https://api.example.com >> api.log
# 监控脚本
#!/bin/bash
while true; do
STATUS=$(curl -w "%{http_code}" -o /dev/null -s https://api.example.com/health)
echo "$(date): $STATUS"
[ "$STATUS" != "200" ] && echo "Alert: API unhealthy!" | mail -s "API Alert" admin@example.com
sleep 60
done
```
### 性能对比表
| 优化项 | 优化前 | 优化后 | 提升 |
| ------ | ------ | ---------- | ------ |
| 连接复用 | 每次新建连接 | Keep-Alive | 30-50% |
| 压缩传输 | 原始大小 | Gzip 压缩 | 60-80% |
| 并发请求 | 串行执行 | 并行处理 | 3-5倍 |
| DNS 缓存 | 每次解析 | 缓存结果 | 10-20% |
| 断点续传 | 重新下载 | 续传 | 节省带宽 |
### 完整优化示例
```bash
#!/bin/bash
# 生产级 API 调用脚本
# 配置
API_URL="https://api.example.com/v1/data"
TOKEN="${API_TOKEN:-$(cat ~/.api_token)}"
TIMEOUT=30
RETRY=3
# 调用函数
optimized_call() {
curl -s -S \
--connect-timeout 10 \
--max-time "$TIMEOUT" \
--retry "$RETRY" \
--retry-delay 2 \
--compressed \
--tlsv1.2 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "User-Agent: MyApp/1.0" \
-w "\n{\"status\":${http_code},\"time\":${time_total},\"size\":${size_download}}\n" \
"$@"
}
# 执行
response=$(optimized_call "$API_URL")
# 处理响应
if [ $? -eq 0 ]; then
echo "Success: $response" | jq '.'
else
echo "Error: Request failed"
exit 1
fi
```
服务端 · 3月7日 19:38
cURL 如何实现文件上传功能?**文件上传**是 cURL 的重要功能,支持多种上传方式,包括表单上传、二进制上传、多文件上传等。
### 基本文件上传
使用 `-F` 或 `--form` 参数进行表单方式上传:
```bash
# 上传单个文件
curl -X POST https://api.example.com/upload \
-F "file=@/path/to/file.pdf"
# 指定 MIME 类型
curl -X POST https://api.example.com/upload \
-F "file=@/path/to/image.png;type=image/png"
# 指定服务器接收的文件名
curl -X POST https://api.example.com/upload \
-F "file=@/path/to/local.txt;filename=uploaded.txt"
```
### 多文件上传
```bash
# 上传多个文件
curl -X POST https://api.example.com/upload \
-F "file1=@/path/to/file1.pdf" \
-F "file2=@/path/to/file2.jpg" \
-F "file3=@/path/to/file3.txt"
# 使用数组形式上传多个文件
curl -X POST https://api.example.com/upload \
-F "files[]=@/path/to/file1.pdf" \
-F "files[]=@/path/to/file2.jpg"
# 混合文件和表单数据
curl -X POST https://api.example.com/submit \
-F "name=张三" \
-F "email=zhangsan@example.com" \
-F "avatar=@/path/to/avatar.jpg" \
-F "resume=@/path/to/resume.pdf"
```
### 二进制文件上传
```bash
# 使用 --data-binary 上传原始二进制数据
curl -X POST https://api.example.com/upload \
-H "Content-Type: application/octet-stream" \
--data-binary @/path/to/file.bin
# 从标准输入读取
cat file.bin | curl -X POST https://api.example.com/upload \
-H "Content-Type: application/octet-stream" \
--data-binary @-
# 上传并显示进度
curl -X POST https://api.example.com/upload \
-F "file=@/path/to/large.zip" \
--progress-bar
```
### Base64 编码上传
```bash
# 将文件编码为 Base64 后上传
curl -X POST https://api.example.com/upload \
-H "Content-Type: application/json" \
-d "{\"file\":\"$(base64 -w 0 /path/to/file.pdf)\",\"filename\":\"document.pdf\"}"
```
### 分块上传(大文件)
```bash
# 上传大文件并显示进度
curl -X POST https://api.example.com/upload \
-F "file=@/path/to/large_file.zip" \
-H "Authorization: Bearer token123" \
--progress-bar | tee upload.log
# 断点续传(需要服务器支持)
curl -C - -X POST https://api.example.com/upload \
-F "file=@/path/to/large_file.zip"
```
### 上传到云存储
```bash
# AWS S3 上传
curl -X PUT "https://bucket.s3.amazonaws.com/file.pdf" \
-H "Content-Type: application/pdf" \
-H "Authorization: AWS4-HMAC-SHA256 ..." \
--data-binary @/path/to/file.pdf
# 使用预签名 URL 上传
curl -X PUT "https://presigned-url-here" \
-H "Content-Type: application/pdf" \
--data-binary @/path/to/file.pdf
```
### 关键参数说明
| 参数 | 作用 | 示例 |
| --------------- | ---------- | ------------------------------------- |
| `-F` 或 `--form` | 表单上传 | `-F "file=@path"` |
| `@` | 读取文件 | `@/path/to/file` |
| `;type=` | 指定 MIME 类型 | `file=@img.png;type=image/png` |
| `;filename=` | 指定文件名 | `file=@local.txt;filename=remote.txt` |
| `--data-binary` | 二进制上传 | `--data-binary @file.bin` |
| `-C -` | 断点续传 | `-C -` |
### 完整上传示例
```bash
# 带认证和元数据的完整上传
curl -X POST https://api.example.com/v1/files/upload \
-H "Authorization: Bearer your_token" \
-H "X-Upload-Category: documents" \
-F "file=@/path/to/document.pdf" \
-F "metadata={\"title\":\"合同文档\",\"tags\":[\"legal\",\"contract\"]};type=application/json" \
--progress-bar \
-o response.json
# 查看上传结果
cat response.json | jq
```
### 常见问题解决
```bash
# 问题 1:文件路径错误
# 解决:使用绝对路径或确认相对路径正确
# 问题 2:权限不足
# 解决:检查文件读取权限
ls -l /path/to/file
# 问题 3:上传大小限制
# 解决:分块上传或联系服务器管理员
# 问题 4:超时
# 解决:增加超时时间
curl --max-time 600 -F "file=@large.zip" https://api.example.com/upload
```
服务端 · 3月7日 19:37
如何使用 cURL 进行 API 调试和排错?**调试和排错**是 cURL 的重要应用场景。掌握调试技巧能快速定位网络请求问题、API 故障和性能瓶颈。
### 基本调试参数
```bash
# 显示详细信息(最常用)
curl -v https://api.example.com
# 仅显示响应头
curl -I https://api.example.com
# 显示响应头和内容
curl -i https://api.example.com
# 静默模式(不显示进度)
curl -s https://api.example.com
# 显示错误信息
curl -S https://api.example.com
```
### 详细输出模式
```bash
# -v 显示完整的请求和响应过程
curl -v https://api.example.com/users
# 输出说明:
# > 表示发送的请求行和请求头
# < 表示接收的响应头
# * 表示连接和 SSL 握手信息
# 更详细的调试信息
curl --trace-ascii debug.log https://api.example.com
# 十六进制格式输出
curl --trace debug.hex https://api.example.com
```
### 响应时间分析
```bash
# 显示传输统计信息
curl -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" \
-o /dev/null -s https://api.example.com
# 完整的性能分析
curl -w "DNS解析: %{time_namelookup}s\nTCP连接: %{time_connect}s\nSSL握手: %{time_appconnect}s\n首字节: %{time_starttransfer}s\n总时间: %{time_total}s\n下载大小: %{size_download}bytes\n下载速度: %{speed_download}bytes/s\n" \
-o /dev/null -s https://api.example.com
# 输出到文件
curl -w "@curl-format.txt" -o /dev/null -s https://api.example.com
```
### 常用调试变量
| 变量 | 说明 |
| -------------------- | ------------ |
| `time_namelookup` | DNS 解析时间 |
| `time_connect` | TCP 连接时间 |
| `time_appconnect` | SSL/SSH 握手时间 |
| `time_starttransfer` | 首字节时间(TTFB) |
| `time_total` | 总时间 |
| `size_download` | 下载大小 |
| `speed_download` | 下载速度 |
| `http_code` | HTTP 状态码 |
### 错误排查技巧
```bash
# 1. 检查 HTTP 状态码
curl -w "\nHTTP Status: %{http_code}\n" -o /dev/null -s https://api.example.com
# 2. 检查重定向链
curl -L -v https://example.com 2>&1 | grep -E "(< HTTP|< Location)"
# 3. 检查 SSL 证书
curl -v https://api.example.com 2>&1 | grep -A 10 "SSL connection"
# 4. 忽略 SSL 证书验证(仅测试用)
curl -k https://self-signed.badssl.com
# 5. 设置超时时间
curl --connect-timeout 5 --max-time 10 https://api.example.com
# 6. 重试机制
curl --retry 3 --retry-delay 2 https://api.example.com
```
### 网络问题诊断
```bash
# 测试连接性
curl -v telnet://example.com:80
# 检查代理设置
curl -v --proxy http://proxy.example.com:8080 https://api.example.com
# 指定 DNS 服务器
curl --dns-servers 8.8.8.8 https://api.example.com
# 强制使用 IPv4
curl -4 https://api.example.com
# 强制使用 IPv6
curl -6 https://api.example.com
# 查看路由追踪
curl -v --trace-time https://api.example.com
```
### 完整调试脚本
```bash
#!/bin/bash
# API 调试脚本
URL="https://api.example.com/users"
TOKEN="your_token_here"
echo "========== 请求信息 =========="
echo "URL: $URL"
echo "Time: $(date)"
echo ""
echo "========== 详细请求过程 =========="
curl -v -X GET "$URL" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
2>&1
echo ""
echo "========== 性能指标 =========="
curl -w "DNS解析: %{time_namelookup}s\nTCP连接: %{time_connect}s\nSSL握手: %{time_appconnect}s\n首字节: %{time_starttransfer}s\n总时间: %{time_total}s\nHTTP状态: %{http_code}\n" \
-o /dev/null -s "$URL" \
-H "Authorization: Bearer $TOKEN"
echo ""
echo "========== 响应内容 =========="
curl -s "$URL" -H "Authorization: Bearer $TOKEN" | jq '.'
```
### 常见问题排查清单
```bash
# 1. 连接超时
curl --connect-timeout 10 https://api.example.com
# 2. 读取超时
curl --max-time 30 https://api.example.com
# 3. DNS 解析问题
curl --resolve example.com:443:192.168.1.100 https://example.com
# 4. 证书问题
curl --cacert /path/to/ca.crt https://api.example.com
# 5. 编码问题
curl -H "Accept-Charset: UTF-8" https://api.example.com
# 6. 压缩传输
curl --compressed https://api.example.com
```
### 日志记录
```bash
# 保存完整调试日志
curl -v https://api.example.com > response.txt 2>&1
# 分别保存请求和响应
curl -v https://api.example.com \
--trace-ascii request-trace.txt \
-o response-body.txt
# 时间戳日志
curl --trace-time -v https://api.example.com 2>&1 | tee debug.log
```
服务端 · 3月7日 19:37
cURL 如何设置请求头(Headers)?在 cURL 中,**请求头(Request Headers)** 用于传递元数据,如认证信息、内容类型等。正确设置请求头对于 API 调用至关重要。
### 基本语法
使用 `-H` 或 `--header` 参数添加请求头:
```bash
curl -H "Header-Name: Header-Value" URL
```
### 常用请求头示例
```bash
# 设置 Content-Type
curl -H "Content-Type: application/json" \
https://api.example.com/users
# 设置 Authorization(Bearer Token)
curl -H "Authorization: Bearer your_token_here" \
https://api.example.com/protected
# 设置 User-Agent
curl -H "User-Agent: MyApp/1.0" \
https://api.example.com/data
# 设置 Accept(期望的响应格式)
curl -H "Accept: application/json" \
https://api.example.com/users
# 设置多个请求头
curl -H "Content-Type: application/json" \
-H "Authorization: Bearer token123" \
-H "Accept: application/json" \
-H "X-Custom-Header: custom-value" \
https://api.example.com/users
```
### 常见请求头类型
| 请求头 | 用途 | 示例 |
| ------------- | --------- | --------------------------------------------------- |
| Content-Type | 指定请求体格式 | application/json, application/x-www-form-urlencoded |
| Authorization | 身份认证 | Bearer token, Basic auth |
| Accept | 期望的响应格式 | application/json, text/html |
| User-Agent | 客户端标识 | Mozilla/5.0, MyApp/1.0 |
| Cookie | 发送 Cookie | session\_id=abc123 |
| Cache-Control | 缓存控制 | no-cache |
### 特殊用法
```bash
# 发送 Cookie
curl -H "Cookie: session_id=abc123; user_id=456" \
https://api.example.com/profile
# 跨域请求
curl -H "Origin: https://example.com" \
-H "Access-Control-Request-Method: POST" \
https://api.example.com/data
# 压缩请求
curl -H "Content-Encoding: gzip" \
--data-binary @compressed.gz \
https://api.example.com/upload
# 从文件读取请求头
curl -H @headers.txt https://api.example.com/users
```
### 注意事项
1. **格式要求**:请求头必须为 "Name: Value" 格式,冒号后有空格
2. **大小写**:HTTP 头部名称不区分大小写,但建议遵循规范
3. **特殊字符**:如果值包含空格或特殊字符,需要用引号包裹
4. **重复设置**:多次使用 `-H` 设置同一头部,后者会覆盖前者
服务端 · 3月7日 19:36
cURL 如何处理 URL 编码和特殊字符?在 cURL 中处理 URL 编码和特殊字符是常见需求,特别是在发送包含空格、中文或特殊符号的数据时。正确编码能确保请求被正确解析。
### URL 编码基础
URL 编码(Percent Encoding)将特殊字符转换为 `%XX` 格式,其中 `XX` 是字符的十六进制 ASCII 码。
```bash
# 需要编码的常见字符
空格 -> %20 或 +
& -> %26
= -> %3D
? -> %3F
# -> %23
% -> %25
中文 -> %E4%B8%AD%E6%96%87
```
### cURL 的编码方式
#### 1. --data-urlencode 自动编码
```bash
# 自动对数据进行 URL 编码
curl -X POST https://api.example.com/search \
--data-urlencode "query=hello world"
# 结果:query=hello%20world
# 编码特殊字符
curl -X POST https://api.example.com/search \
--data-urlencode "query=foo&bar=baz"
# 结果:query=foo%26bar%3Dbaz
# 编码中文字符
curl -X POST https://api.example.com/search \
--data-urlencode "query=中文搜索"
# 结果:query=%E4%B8%AD%E6%96%87%E6%90%9C%E7%B4%A2
```
#### 2. 手动编码
```bash
# 使用 printf 进行编码
ENCODED=$(printf '%s' 'hello world' | od -An -tx1 | tr -d ' \n' | sed 's/../%&/g')
curl -X POST -d "query=$ENCODED" https://api.example.com/search
# 使用 Python 编码
ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('hello world'))")
curl -X POST -d "query=$ENCODED" https://api.example.com/search
# 使用 jq 编码
ENCODED=$(jq -nr --arg s 'hello world' '$s|@uri')
curl -X POST -d "query=$ENCODED" https://api.example.com/search
```
### URL 中的特殊字符处理
#### 查询参数中的特殊字符
```bash
# 错误方式:& 会被解释为参数分隔符
curl "https://api.example.com/search?q=foo&bar=baz"
# 实际发送两个参数:q=foo 和 bar=baz
# 正确方式:手动编码
curl "https://api.example.com/search?q=foo%26bar%3Dbaz"
# 或使用 --data-urlencode(自动处理 &)
curl -G https://api.example.com/search \
--data-urlencode "q=foo&bar=baz"
```
#### 路径中的特殊字符
```bash
# 路径中包含空格
curl "https://api.example.com/files/my%20document.pdf"
# 路径中包含中文
curl "https://api.example.com/files/%E4%B8%AD%E6%96%87%E6%96%87%E4%BB%B6.pdf"
# 使用 --path-as-is 保留特殊路径
curl --path-as-is "https://api.example.com/../secret.txt"
```
### 不同场景的处理方式
#### 场景 1:表单数据提交
```bash
# 使用 --data-urlencode 自动编码表单数据
curl -X POST https://api.example.com/submit \
--data-urlencode "name=张三" \
--data-urlencode "email=zhangsan@example.com" \
--data-urlencode "message=Hello World! 你好世界!"
# 混合使用编码和非编码数据
curl -X POST https://api.example.com/submit \
-d "id=123" \
--data-urlencode "content=Special chars: & = ?"
```
#### 场景 2:URL 查询参数
```bash
# 使用 -G 和 --data-urlencode 构建查询字符串
curl -G https://api.example.com/search \
--data-urlencode "q=hello world" \
--data-urlencode "category=技术&编程" \
--data-urlencode "page=1"
# 结果 URL:
# https://api.example.com/search?q=hello%20world&category=%E6%8A%80%E6%9C%AF%26%E7%BC%96%E7%A8%8B&page=1
```
#### 场景 3:JSON 数据中的特殊字符
```bash
# JSON 中的特殊字符需要转义
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name":"张三","bio":"Line1\nLine2\tTabbed"}'
# 使用 jq 处理复杂 JSON
jq -n '{name: "张三", bio: "Line1\nLine2"}' | \
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d @-
```
### 编码工具函数
```bash
# URL 编码函数
url_encode() {
local string="$1"
local encoded=""
local pos c o
for (( pos=0; pos<${#string}; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9]) encoded+="$c" ;;
*) printf -v o '%%%02x' "'$c"; encoded+="$o" ;;
esac
done
echo "$encoded"
}
# 使用示例
QUERY=$(url_encode "hello world & more")
curl "https://api.example.com/search?q=$QUERY"
```
### 常见编码问题
```bash
# 问题 1:空格被错误处理
# 错误:
curl "https://api.example.com/search?q=hello world"
# 正确:
curl "https://api.example.com/search?q=hello%20world"
# 问题 2:& 符号被解释为分隔符
# 错误:
curl "https://api.example.com/search?q=A&B"
# 正确:
curl "https://api.example.com/search?q=A%26B"
# 问题 3:中文乱码
# 错误:
curl "https://api.example.com/search?q=中文"
# 正确:
curl "https://api.example.com/search?q=%E4%B8%AD%E6%96%87"
```
### 完整示例脚本
```bash
#!/bin/bash
# URL 编码处理示例
API_BASE="https://api.example.com/v1"
# 编码函数
urlencode() {
python3 -c "import urllib.parse; print(urllib.parse.quote('''$1'''))"
}
# 搜索请求
search_query="hello world & special chars: 中文"
encoded_query=$(urlencode "$search_query")
echo "Original: $search_query"
echo "Encoded: $encoded_query"
# 发送请求
curl -G "${API_BASE}/search" \
--data-urlencode "q=$search_query" \
-H "Accept: application/json"
# 表单提交
form_data="name=张三&email=test@example.com&msg=Hello World!"
curl -X POST "${API_BASE}/submit" \
--data-urlencode "name=张三" \
--data-urlencode "email=test@example.com" \
--data-urlencode "msg=Hello World!"
```
### 最佳实践
1. **优先使用 `--data-urlencode`**:自动处理编码,避免错误
2. **查询参数使用 `-G`**:配合 `--data-urlencode` 构建 URL
3. **JSON 使用工具生成**:用 `jq` 处理复杂 JSON,自动转义
4. **避免手动拼接 URL**:容易遗漏编码,导致请求失败
5. **测试编码结果**:使用 `-v` 查看实际发送的 URL
服务端 · 3月7日 19:36
cURL 如何配置和使用代理服务器?**代理设置**是 cURL 在企业环境和网络调试中的重要功能。正确配置代理能突破网络限制、保护隐私和进行流量分析。
### 基本代理设置
```bash
# HTTP 代理
curl -x http://proxy.example.com:8080 https://api.example.com
curl --proxy http://proxy.example.com:8080 https://api.example.com
# HTTPS 代理
curl -x https://proxy.example.com:443 https://api.example.com
# SOCKS 代理
curl -x socks5://proxy.example.com:1080 https://api.example.com
curl -x socks5h://proxy.example.com:1080 https://api.example.com
```
### 代理认证
```bash
# 用户名密码认证
curl -x http://user:password@proxy.example.com:8080 https://api.example.com
# 使用 -U 参数
curl -x http://proxy.example.com:8080 -U user:password https://api.example.com
# NTLM 认证
curl -x http://proxy.example.com:8080 \
--proxy-ntlm \
-U user:password \
https://api.example.com
# Digest 认证
curl -x http://proxy.example.com:8080 \
--proxy-digest \
-U user:password \
https://api.example.com
```
### 代理类型对比
| 代理类型 | 协议 | 特点 | 使用场景 |
| ------- | ---------- | -------- | ------- |
| HTTP | http\:// | 明文传输 | 简单代理、缓存 |
| HTTPS | https\:// | 加密传输 | 安全代理 |
| SOCKS4 | socks4:// | TCP 转发 | 基础代理 |
| SOCKS5 | socks5:// | 支持UDP、认证 | 高级代理 |
| SOCKS5H | socks5h:// | DNS 远程解析 | 隐私保护 |
### 环境变量配置
```bash
# 设置环境变量
export http_proxy="http://proxy.example.com:8080"
export https_proxy="http://proxy.example.com:8080"
export HTTP_PROXY="http://proxy.example.com:8080"
export HTTPS_PROXY="http://proxy.example.com:8080"
export no_proxy="localhost,127.0.0.1,.example.com"
# 使用环境变量
curl https://api.example.com
# 忽略环境变量
curl --noproxy "*" https://api.example.com
```
### 代理绕过
```bash
# 绕过特定域名
curl --noproxy "localhost,127.0.0.1,internal.example.com" \
-x http://proxy.example.com:8080 \
https://api.example.com
# 绕过所有代理
curl --noproxy "*" https://api.example.com
```
### 代理调试
```bash
# 查看代理连接过程
curl -v -x http://proxy.example.com:8080 https://api.example.com 2>&1 | grep -i proxy
# 测试代理连通性
curl -v -x http://proxy.example.com:8080 http://www.google.com
# 通过代理查看真实 IP
curl -x http://proxy.example.com:8080 https://api.ipify.org
```
### 高级代理配置
```bash
# 代理自动配置(PAC)
curl --proxy-header "User-Agent: MyApp/1.0" \
-x http://proxy.example.com:8080 \
https://api.example.com
# 代理隧道(用于 HTTPS)
curl -x http://proxy.example.com:8080 \
--proxy-tunnel \
https://api.example.com
# 指定代理服务器的 TLS 版本
curl -x https://proxy.example.com:443 \
--proxy-tlsv1.2 \
https://api.example.com
# 代理证书验证
curl -x https://proxy.example.com:443 \
--proxy-cacert /path/to/proxy-ca.crt \
https://api.example.com
# 忽略代理证书验证
curl -x https://proxy.example.com:443 \
--proxy-insecure \
https://api.example.com
```
### 实战场景
```bash
# 场景 1:企业内网访问外网
curl -x http://corporate-proxy.company.com:8080 \
-U "domain\\username:password" \
https://api.github.com/user
# 场景 2:使用 SSH 隧道作为代理
# 先建立隧道:ssh -D 1080 user@remote-server
curl -x socks5://localhost:1080 https://api.example.com
# 场景 3:负载测试通过代理
for i in {1..10}; do
curl -x http://proxy.example.com:8080 \
-w "Request $i: %{http_code}\n" \
-o /dev/null -s \
https://api.example.com &
done
wait
# 场景 4:抓包分析
# 配合 Charles/Fiddler 使用
curl -x http://localhost:8888 \
-k \
https://api.example.com
```
### 代理配置文件
```bash
# ~/.curlrc 配置文件
proxy = "http://proxy.example.com:8080"
proxy-user = "username:password"
noproxy = "localhost,127.0.0.1"
# 使用配置文件
curl https://api.example.com
# 忽略配置文件
curl -q https://api.example.com
```
### 常见问题解决
```bash
# 问题 1:代理连接超时
# 解决:增加超时时间
curl -x http://proxy.example.com:8080 \
--connect-timeout 30 \
https://api.example.com
# 问题 2:代理认证失败
# 解决:检查认证方式和凭据
curl -v -x http://proxy.example.com:8080 \
--proxy-ntlm -U "domain\\user:pass" \
https://api.example.com
# 问题 3:HTTPS 通过 HTTP 代理失败
# 解决:使用 CONNECT 方法(默认)或隧道
curl -x http://proxy.example.com:8080 \
--proxy-tunnel \
https://api.example.com
# 问题 4:DNS 泄露
# 解决:使用 socks5h 让代理服务器解析 DNS
curl -x socks5h://proxy.example.com:1080 \
https://api.example.com
# 问题 5:代理服务器证书问题
# 解决:指定 CA 或忽略验证
curl -x https://proxy.example.com:443 \
--proxy-insecure \
https://api.example.com
```
### 完整代理示例
```bash
# 企业级代理配置
curl -x http://corporate-proxy.company.com:8080 \
--proxy-ntlm \
-U "COMPANY\\username:password" \
--proxy-header "User-Agent: CorporateApp/1.0" \
--noproxy "localhost,127.0.0.1,*.internal.company.com" \
--connect-timeout 30 \
--max-time 60 \
-H "Authorization: Bearer api_token" \
https://api.external-service.com/data
```
服务端 · 3月6日 23:08
cURL 如何处理 HTTP 重定向?**重定向处理**是 cURL 访问 Web 资源时的常见需求。正确处理重定向能确保请求到达最终目标地址。
### 基本重定向处理
```bash
# 不跟随重定向(默认行为)
curl http://example.com
# 自动跟随重定向
curl -L http://example.com
curl --location http://example.com
# 显示重定向过程
curl -L -v http://example.com
```
### 重定向次数限制
```bash
# 限制最大重定向次数(默认 50 次)
curl -L --max-redirs 5 http://example.com
# 无限重定向(不推荐)
curl -L --max-redirs -1 http://example.com
```
### POST 请求重定向行为
```bash
# 默认:POST 重定向后转为 GET
curl -L -X POST -d "data=test" http://example.com/submit
# 保持 POST 方法(RFC 7231)
curl -L --post301 -X POST -d "data=test" http://example.com/submit
# 保持 POST 方法(非标准)
curl -L --post302 -X POST -d "data=test" http://example.com/submit
curl -L --post303 -X POST -d "data=test" http://example.com/submit
```
### 重定向类型说明
| 状态码 | 类型 | 默认行为 |
| --- | --------- | ---------- |
| 301 | 永久重定向 | POST → GET |
| 302 | 临时重定向 | POST → GET |
| 303 | See Other | POST → GET |
| 307 | 临时重定向 | 保持方法 |
| 308 | 永久重定向 | 保持方法 |
### 查看重定向链
```bash
# 显示所有重定向 URL
curl -L -v http://example.com 2>&1 | grep -E "(< HTTP|< Location)"
# 使用 -w 输出最终 URL
curl -L -w "Final URL: %{url_effective}\n" -o /dev/null -s http://example.com
# 获取重定向次数
curl -L -w "Redirects: %{num_redirects}\n" -o /dev/null -s http://example.com
```
### 常见重定向场景
```bash
# HTTP 到 HTTPS 重定向
curl -L http://example.com
# www 到非 www 重定向
curl -L http://www.example.com
# 短链接展开
curl -L -w "Final URL: %{url_effective}\n" -o /dev/null -s https://bit.ly/shorturl
# 登录后重定向
curl -L -c cookies.txt -b cookies.txt \
-X POST \
-d "username=admin&password=123456" \
http://example.com/login
```
### 高级重定向控制
```bash
# 限制重定向协议
curl -L --proto-redir =https http://example.com
# 重定向时保持请求头
curl -L --location-trusted \
-H "Authorization: Bearer token123" \
http://example.com/api
# 查看重定向前后的 Cookie
curl -L -c cookies.txt -b cookies.txt -v http://example.com 2>&1 | grep -i cookie
# 重定向时修改请求头
curl -L -H "Host: newdomain.com" http://example.com
```
### 重定向调试脚本
```bash
#!/bin/bash
# 重定向追踪脚本
URL="http://example.com"
echo "========== 重定向链追踪 =========="
echo "初始 URL: $URL"
echo ""
# 方法一:使用 -v 查看
curl -L -v "$URL" 2>&1 | grep -E "(< HTTP|< Location)" | head -20
echo ""
echo "========== 最终信息 =========="
# 获取最终 URL
FINAL_URL=$(curl -L -w "%{url_effective}" -o /dev/null -s "$URL")
echo "最终 URL: $FINAL_URL"
# 获取重定向次数
REDIRECTS=$(curl -L -w "%{num_redirects}" -o /dev/null -s "$URL")
echo "重定向次数: $REDIRECTS"
# 获取最终状态码
STATUS=$(curl -L -w "%{http_code}" -o /dev/null -s "$URL")
echo "最终状态码: $STATUS"
```
### 常见问题解决
```bash
# 问题 1:重定向循环
# 解决:限制重定向次数
curl -L --max-redirs 10 http://example.com
# 问题 2:跨域重定向丢失认证
# 解决:使用 --location-trusted
curl -L --location-trusted -H "Authorization: Bearer token" http://example.com
# 问题 3:POST 数据丢失
# 解决:使用 --post302 或 --post301
curl -L --post302 -X POST -d "data=test" http://example.com
# 问题 4:HTTPS 重定向失败
# 解决:确保 SSL 证书有效或使用 -k
curl -L -k http://example.com
# 问题 5:重定向到不同域名
# 解决:检查并更新 Host 头
curl -L -H "Host: newdomain.com" http://example.com
```
### 实战示例
```bash
# 完整的重定向感知 API 调用
curl -L --max-redirs 5 \
--post302 \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer token123" \
-d '{"action":"submit"}' \
-w "\n最终URL: %{url_effective}\n重定向次数: %{num_redirects}\nHTTP状态: %{http_code}\n" \
http://api.example.com/submit
# 短链接批量展开
for url in "bit.ly/abc" "t.co/xyz"; do
echo -n "$url -> "
curl -L -w "%{url_effective}" -o /dev/null -s "https://$url"
echo ""
done
```
服务端 · 3月6日 23:08