乐闻世界logo
搜索文章和话题

cURL

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