HTTP Header:基础与排障

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。

HTTP(Hypertext Transfer Protocol,超文本传输协议)的 Header 是请求和响应的元数据。先确定谁写、谁读、在哪一跳发生变化,再判断配置是否正确。 字段名不区分大小写,字段值是否区分取决于具体字段。

1. 常用字段与职责#

方向 Header 作用/容易踩的坑
请求 Host HTTP/1.1 的目标站点;HTTP/2、HTTP/3 通常用 :authority;用于虚拟主机和路由,不能直接信任它来拼重置密码链接
请求 Authorization 身份凭证;必须验证,日志脱敏,避免带凭证跨域重定向
请求/响应 Content-Type 当前消息体格式,例如 application/json;与文件扩展名不是一回事
请求 Accept、Accept-Encoding 希望收到的媒体类型、压缩编码;不是声明请求体格式
请求 Origin 发起请求的源(协议、主机、端口);非浏览器可伪造,不能用于身份认证
请求/响应 Cookie/Set-Cookie 浏览器发送已有 Cookie/服务端设置 Cookie;每个 Cookie 独立一个 Set-Cookie,不要用逗号合并
请求 X-Forwarded-For、X-Forwarded-Proto 代理传递客户端地址、原始协议;仅信任受控代理写入的部分
请求/响应 traceparent、X-Request-ID 跨服务追踪/请求关联;前者是标准追踪上下文,后者是常见约定,都不是授权依据
响应 Cache-Control、ETag、Vary 缓存策略、表示版本、缓存按哪些请求头区分
请求 If-None-Match 带上此前的 ETag;GET 内容未变通常返回 304,客户端复用缓存正文
响应 Location、Retry-After 重定向目标、建议何时重试;仍需限制重试次数并避免重复写入

Cookie 常用属性:Secure 限 HTTPS,HttpOnly 限制脚本读取,SameSite 控制跨站携带;SameSite=None 需要 Secure。这些不能替代服务端会话验证或防跨站请求伪造措施。

2. 三类最常见问题#

缓存:不要把用户 A 的数据交给用户 B#

内容 策略示例 含义
含凭证/敏感业务数据 Cache-Control: no-store 不存储本次响应;不会自动清除历史缓存
可保存、每次必须校验 Cache-Control: no-cache + ETag 可以缓存,但复用前必须向服务端验证
用户私有、短时可缓存 Cache-Control: private, max-age=60 允许浏览器缓存,禁止共享缓存存储
文件名含内容哈希的公开静态资源 Cache-Control: public, max-age=31536000, immutable 适合不可变资源;更新时更换文件名

Vary: Accept-Encoding 区分压缩版本;响应根据 Origin 动态变化时使用 Vary: Origin,并核对 CDN(Content Delivery Network,内容分发网络)的实际缓存键。ALB 本身不是内容缓存。参见 HTTP 缓存标准。

跨域:CORS 不等于鉴权#

完整的 OPTIONS → 业务请求 → 浏览器放行过程,见 浏览器跨域请求时序。

CORS(Cross-Origin Resource Sharing,跨源资源共享)决定浏览器脚本能否读取跨源响应。简单请求可能已执行后才被浏览器限制读取,因此不能靠 CORS 阻止写操作。

  • 非简单请求通常先发 OPTIONS 预检,携带 Origin、Access-Control-Request-Method 和所需请求头。
  • 服务端返回匹配的 Access-Control-Allow-Origin/Methods/Headers;实际业务响应也需要正确的跨域头。
  • 携带 Cookie 等凭证时,允许源必须是具体源,不能是 *;还需 Access-Control-Allow-Credentials: true,浏览器请求也需启用凭证。
  • 多源白名单由应用逐个匹配,拒绝未知源;不能把多个源用逗号写入 Allow-Origin,也不能无条件回显 Origin。
  • 预检一般不带业务凭证;允许合法预检通过,同时保持实际接口鉴权。读取自定义响应头需 Access-Control-Expose-Headers。

协议细节见 Fetch CORS 标准。

安全响应头:由浏览器执行#

Header 作用 上线要求
Strict-Transport-Security HSTS(HTTP Strict Transport Security,HTTP 严格传输安全),让浏览器后续强制 HTTPS 从短 max-age 开始;确认所有子域后再考虑 includeSubDomains,不要直接 preload
Content-Security-Policy CSP(Content Security Policy,内容安全策略),限制脚本、资源、嵌入等 先用应用的 Content-Security-Policy-Report-Only 观察,再强制;动态 nonce 由应用生成
X-Content-Type-Options: nosniff 阻止部分内容类型猜测 先确保脚本/样式的 Content-Type 正确
X-Frame-Options: DENY 禁止页面被嵌入 frame 有合法嵌入需求时评估 CSP frame-ancestors

HSTS 不替代首次访问的 HTTP→HTTPS 重定向,也不保证代理到后端加密。浏览器已保存的策略不会因为服务端删除这个头而立即消失。

3. Hands-on:验收真实预发布服务#

前提:已有你负责的 HTTPS 预发布 API(Application Programming Interface,应用程序接口),一个无副作用的 GET 路径、一个已配置 ETag 的公开静态文件,以及一个配置了 CORS 的接口。以下地址和路径必须替换;这是一套真实服务验收步骤,不会替你创建服务。

第一步:观察响应,而不是只看配置#

export BASE='https://api.staging.example.com'
export READ_PATH='/health/ready'
export CORS_PATH='/api/catalog'
export ORIGIN='https://portal.staging.example.com'
umask 077
HEADER_WORK=$(mktemp -d)
# GET 观察真实处理路径;HEAD 可能由不同代码处理。暂不跟随重定向。
curl -sS --max-time 15 -D "$HEADER_WORK/get.headers" -o /dev/null "$BASE$READ_PATH"
cat "$HEADER_WORK/get.headers"

记录状态码、Content-Type、安全头、缓存头和关联 ID。用浏览器 Network 同时核对;如果是 301/302,先检查 Location 的协议、域名,避免盲目跟随掩盖循环。

第二步:检查缓存协商#

export ASSET_PATH='/assets/app.CONTENT_HASH.js' # 换成真实、有 ETag 的文件
curl -sS --max-time 15 -D "$HEADER_WORK/asset.headers" -o /dev/null "$BASE$ASSET_PATH"
ETAG=$(awk 'tolower($1)=="etag:" {sub(/^[^:]*:[ \t]*/, ""); sub(/\r$/, ""); print; exit}' "$HEADER_WORK/asset.headers")
test -n "$ETAG" && curl -sS --max-time 15 -D - -o /dev/null -H "If-None-Match: $ETAG" "$BASE$ASSET_PATH"

未变化时预期 304;无 ETag 则这项不适用,不是 curl 故障。敏感接口另检查 no-store;不要用真实凭证进行 curl -v 后把输出贴到工单。

第三步:预检、实际响应、拒绝源分别验证#

curl -sS --max-time 15 -D - -o /dev/null -X OPTIONS "$BASE$CORS_PATH" -H "Origin: $ORIGIN" -H 'Access-Control-Request-Method: GET' -H 'Access-Control-Request-Headers: authorization,content-type'
curl -sS --max-time 15 -D - -o /dev/null "$BASE$CORS_PATH" -H "Origin: $ORIGIN"
curl -sS --max-time 15 -D - -o /dev/null "$BASE$CORS_PATH" -H 'Origin: https://untrusted.example'

预检预期 2xx 且允许所需方法和头。实际响应若需登录可返回 401,但仍应满足允许源的跨域策略;未知源不能得到匹配自己的 Allow-Origin。curl 不执行 CORS:最终必须在真实前端源的浏览器中验证正常调用成功、未知源脚本无法读取;有会话时再验 Cookie 场景。

第四步:验证代理信任边界#

在预发布发送 -H 'X-Forwarded-For: 198.51.100.77',通过受限应用日志观察最终解析的客户端地址;不要公开全量 Header 回显接口。直连 ALB 且 append 模式下,伪造值在前,ALB 追加其看到的连接来源。应用必须按已配置的可信代理链从右向左解析,不能简单取第一个值。有 CDN 时重新核对完整代理链与绕过入口的可能性。

测试后删除本次临时目录:rm -r -- "$HEADER_WORK"。

4. 排障顺序#

现象 优先检查
curl 成功、浏览器失败 OPTIONS 状态、实际响应跨域头、凭证模式、浏览器 Console
页面突然脚本/样式失败 CSP 拒绝信息、nosniff 与 Content-Type 是否冲突
HTTPS 重定向循环 应用是否正确识别可信代理传来的原始协议
客户端地址全是代理/可被伪造 X-Forwarded-For 模式、可信代理范围、是否能直连后端
不同用户读到相同私有内容 Cache-Control、CDN 缓存键、历史缓存清理
应用已改头、外部没变 逐跳比较应用→代理→ALB→CDN;检查覆盖和缓存

AWS 的具体配置与回退见 ALB Header 实战。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭