强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

curl 深度教程 / 第 05 章:请求头与响应头

第 05 章:请求头与响应头

HTTP 头(Headers)是 HTTP 协议的"信封"——它们携带了关于请求和响应的元数据,控制着缓存、认证、内容协商、压缩等关键行为。


5.1 请求头基础

设置请求头

# 设置单个请求头
curl -H "Accept: application/json" https://api.example.com/data

# 设置多个请求头
curl -H "Accept: application/json" \
     -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
     -H "X-Request-ID: 550e8400-e29b-41d4-a716-446655440000" \
     -H "X-Forwarded-For: 203.0.113.50" \
     https://api.example.com/data

# 移除默认请求头(使用空值)
curl -H "Accept:" -H "User-Agent:" https://example.com

# 设置带空格的头部值
curl -H "X-Custom: hello world" https://example.com

# 设置带冒号的头部值
curl -H "Authorization: Basic dXNlcjpwYXNz" https://example.com

常用请求头速查

请求头用途curl 设置方式
Accept指定期望的响应格式-H "Accept: application/json"
Accept-Language语言偏好-H "Accept-Language: zh-CN,en;q=0.9"
Accept-Encoding支持的压缩算法--compressed(自动设置)
Authorization认证凭据-H "Authorization: Bearer token"
Content-Type请求体格式-H "Content-Type: application/json"
Cookie发送 Cookie-b "name=value"
User-Agent客户端标识-A "MyApp/1.0"
Referer来源页面-e "https://example.com"
Origin请求源(CORS)-H "Origin: https://myapp.com"
Cache-Control缓存策略-H "Cache-Control: no-cache"
If-None-Match条件请求(ETag)-H 'If-None-Match: "abc123"'
If-Modified-Since条件请求(时间)-H "If-Modified-Since: Sat, 01 Jan 2025 00:00:00 GMT"
Range请求部分内容-H "Range: bytes=0-999"
Host目标主机-H "Host: virtual.example.com"
X-Forwarded-For客户端真实 IP-H "X-Forwarded-For: 203.0.113.50"

5.2 响应头解析

查看响应头

# 仅显示响应头
curl -I https://example.com

# 输出示例:
# HTTP/2 200
# content-type: text/html; charset=UTF-8
# content-length: 1256
# date: Sat, 10 May 2026 12:00:00 GMT
# server: nginx/1.24.0
# cache-control: max-age=3600
# etag: "67890-abc"
# strict-transport-security: max-age=31536000

# 显示响应头 + 响应体
curl -i https://example.com

# 提取特定响应头
curl -sI https://example.com | grep -i "content-type"

# 仅获取状态码
curl -s -o /dev/null -w "%{http_code}" https://example.com

# 获取完整的头信息(详细模式)
curl -v https://example.com 2>&1 | grep "^[<>]"

常见响应头说明

响应头说明示例值
Status / HTTP 状态行请求结果HTTP/2 200
Content-Type响应体格式application/json; charset=utf-8
Content-Length响应体大小(字节)1256
Content-Encoding压缩算法gzip, br, zstd
Cache-Control缓存策略max-age=3600, no-cache
ETag资源版本标识"67890-abc"
Last-Modified最后修改时间Sat, 10 May 2026 12:00:00 GMT
Set-Cookie设置 Cookiesession=abc; Path=/; HttpOnly
Location重定向目标/new-page
X-Request-ID请求追踪 ID550e8400-...
X-RateLimit-Remaining剩余请求次数99
Strict-Transport-SecurityHSTS 策略max-age=31536000
Access-Control-Allow-OriginCORS 允许的源https://myapp.com

5.3 Content-Type 详解

Content-Type 是最重要的头部之一,它告诉服务器(或客户端)如何解析请求/响应体。

常见 Content-Type

# application/json(REST API 标准)
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name": "张三"}'

# application/x-www-form-urlencoded(HTML 表单默认)
curl -X POST https://example.com/login \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin&password=secret"

# multipart/form-data(文件上传)
curl -X POST https://api.example.com/upload \
  -F "[email protected]" \
  -F "description=风景照"

# text/plain
curl -X POST https://api.example.com/log \
  -H "Content-Type: text/plain" \
  -d "2026-05-10 12:00:00 INFO Application started"

# application/xml(SOAP 服务)
curl -X POST https://soap.example.com/service \
  -H "Content-Type: application/xml; charset=utf-8" \
  -d '<?xml version="1.0"?><request><id>1</id></request>'

# application/octet-stream(二进制数据)
curl -X PUT https://storage.example.com/file.bin \
  -H "Content-Type: application/octet-stream" \
  --data-binary @file.bin

# application/pdf
curl -X POST https://api.example.com/documents \
  -H "Content-Type: application/pdf" \
  --data-binary @document.pdf

Content-Type 对照表

格式Content-Type使用场景
JSONapplication/jsonREST API
表单application/x-www-form-urlencodedHTML 表单
文件上传multipart/form-data文件上传
XMLapplication/xmltext/xmlSOAP、旧系统
纯文本text/plain日志、纯文本
HTMLtext/html网页
CSVtext/csv数据导入/导出
PDFapplication/pdf文档
图片image/png, image/jpeg图片上传
二进制application/octet-stream通用二进制
YAMLapplication/x-yaml配置文件
Protocol Buffersapplication/protobufgRPC、高效序列化
MessagePackapplication/msgpack高效序列化

Cookie 是维持 HTTP 会话状态的核心机制。curl 提供了完整的 Cookie 管理功能。

# 发送 Cookie
curl -b "session=abc123; user=张三" https://example.com

# 发送单个 Cookie
curl -b "session=abc123" https://example.com

# 使用 Cookie 文件
curl -b cookies.txt https://example.com

# 保存服务器设置的 Cookie
curl -c cookies.txt https://example.com

# 同时读取和保存 Cookie(维持会话)
curl -b cookies.txt -c cookies.txt https://example.com/dashboard
# 完整的登录会话流程
# 1. 登录并保存 Cookie
curl -c cookies.txt -X POST https://example.com/login \
  -d "username=admin&password=secret" \
  -L  # 跟随重定向

# 2. 使用 Cookie 访问需要认证的页面
curl -b cookies.txt https://example.com/dashboard

# 3. 查看保存的 Cookie
cat cookies.txt
# 输出示例:
# .example.com	TRUE	/	FALSE	1715347200	session	abc123
# .example.com	TRUE	/	FALSE	1715347200	user	admin

# 4. 登出(可能需要清空 Cookie)
rm cookies.txt
# Netscape Cookie 文件格式
# domain  flag  path  secure  expiry  name  value
.example.com	TRUE	/	TRUE	1715347200	session	abc123
.example.com	TRUE	/	FALSE	1715347200	theme	dark

字段说明:

  • domain:Cookie 所属域名
  • flag:是否适用于所有子域(TRUE/FALSE)
  • path:Cookie 适用路径
  • secure:是否仅 HTTPS 传输
  • expiry:过期时间(Unix 时间戳)
  • name:Cookie 名称
  • value:Cookie 值

5.5 Content Negotiation(内容协商)

# 指定期望的响应格式
curl -H "Accept: application/json" https://api.example.com/users
# 服务器返回 JSON

curl -H "Accept: application/xml" https://api.example.com/users
# 服务器返回 XML

# 多种格式,带优先级(q 值)
curl -H "Accept: application/json;q=0.9, application/xml;q=0.8, */*;q=0.1" \
  https://api.example.com/users

# 语言协商
curl -H "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8" https://example.com

# 编码协商(自动解压)
curl --compressed https://example.com
# 设置了 Accept-Encoding: gzip, deflate, br

5.6 条件请求头

条件请求头用于缓存验证和乐观并发控制。

缓存验证

# ETag 条件请求
# 第一次请求,获取 ETag
curl -sI https://api.example.com/data/42
# 响应:ETag: "v1-abc123"

# 第二次请求,带上 ETag 验证缓存
curl -H 'If-None-Match: "v1-abc123"' https://api.example.com/data/42
# 304 Not Modified → 缓存仍有效

# Last-Modified 条件请求
# 第一次请求
curl -sI https://api.example.com/data/42
# 响应:Last-Modified: Sat, 10 May 2026 12:00:00 GMT

# 第二次请求
curl -H "If-Modified-Since: Sat, 10 May 2026 12:00:00 GMT" \
  https://api.example.com/data/42
# 304 Not Modified → 缓存仍有效

乐观并发控制

# 使用 ETag 防止"丢失更新"
# 1. 获取资源和 ETag
curl -sI https://api.example.com/config
# 响应:ETag: "config-v3"

# 2. 更新时带上 If-Match,确保版本一致
curl -X PUT https://api.example.com/config \
  -H 'If-Match: "config-v3"' \
  -H "Content-Type: application/json" \
  -d '{"key": "new_value"}'
# 成功:200 OK
# 版本冲突:412 Precondition Failed

5.7 自定义头部规范

X- 前缀(已废弃但常见)

# 旧式 X- 前缀自定义头(RFC 6648 已不推荐,但广泛使用)
curl -H "X-Request-ID: 550e8400-e29b-41d4-a716-446655440000" \
     -H "X-Correlation-ID: abc-def-ghi" \
     -H "X-Forwarded-For: 203.0.113.50" \
     -H "X-Real-IP: 203.0.113.50" \
     -H "X-Tenant-ID: tenant-42" \
     https://api.example.com/data

常见自定义头命名

头部用途来源
X-Request-ID请求追踪代理/网关生成
X-Correlation-ID分布式追踪关联应用生成
X-Forwarded-For原始客户端 IP代理添加
X-Real-IP真实客户端 IP代理添加
X-Tenant-ID多租户标识应用层
X-API-KeyAPI 密钥应用层
X-CSRF-TokenCSRF 保护令牌前端获取
X-Idempotency-Key幂等键客户端生成

注意事项

  1. 头部名大小写不敏感:HTTP/2 强制小写,HTTP/1.1 大小写不敏感
  2. 多个同名头部:某些头部(如 Set-Cookie)可以有多个值
  3. 空头部值-H "Header:" 会移除该默认头部
  4. 代理转发HostX-Forwarded-* 头部在经过代理时可能被修改
  5. 安全头部:不要在请求头中暴露敏感信息
# 查看 curl 默认发送的所有请求头
curl -v https://example.com 2>&1 | grep "^>"

# 输出示例:
# > GET / HTTP/2
# > Host: example.com
# > User-Agent: curl/8.5.0
# > Accept: */*

扩展阅读


📖 下一章第 06 章:认证机制 — 深入了解 Basic/Bearer/OAuth2/客户端证书/NTLM/Kerberos 等认证方式。