nginx 应直接拦截 options 请求返回 204,不转发后端;需用 limit_except 或 if+return 终结请求,显式添加带 always 的 cors 头,配合 http/2 连接复用与 tls 会话缓存提升性能。

在启用 HTTP/2 的 Nginx 环境中,OPTIONS 预检请求的高效处理不能只靠“支持 HTTP/2”自动解决——它需要明确拦截、避免穿透、复用连接,并与 HTTP/2 的多路复用特性协同工作。否则,高频 OPTIONS 仍会消耗连接资源、触发重复 TLS 握手、拖慢整体 API 响应。
直接拦截 OPTIONS 请求,不转发到后端
HTTP/2 虽支持多路复用,但若 OPTIONS 请求仍被 proxy_pass 到后端,就失去了“就近响应”的优势。Nginx 应在配置层直接终结预检,返回 204 并携带完整 CORS 头。
- 使用 limit_except 块替代 if + return:更安全、语义清晰,避免 Nginx 的 if 陷阱
- 匹配路径要精准,例如 location /api/ { ... },避免泛匹配影响静态资源
- 必须显式添加 Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers 和 Access-Control-Max-Age
- 返回前设 Content-Length 0 和 Content-Type text/plain; charset=utf-8,确保浏览器正确解析 204
让预检响应也受益于 HTTP/2 连接复用
即使 OPTIONS 不打后端,它仍需走完 TLS 握手和 HTTP/2 连接建立流程。若未开启会话复用或缓存策略,每个新 OPTIONS 请求都可能新建连接。
- 全局启用 ssl_session_cache shared:SSL:10m 和 ssl_session_timeout 4h,提升 TLS 会话复用率
- 确保 listen 443 ssl http2 已生效,且禁用 TLSv1.0/v1.1,仅保留 TLSv1.2/TLSv1.3
- 对 OPTIONS 响应也设置合理 Access-Control-Max-Age(建议 3600–86400),减少重复预检
- 避免在 OPTIONS 块中误加 proxy_set_header 或 proxy_pass,防止隐式启用代理逻辑
配合 upstream keepalive,保障后续真实请求的连接效率
OPTIONS 虽快,但紧随其后的 POST/PUT 等真实请求更依赖稳定、复用的上游连接。HTTP/2 客户端连接再好,后端链路若频繁断连,整体性能仍受限。
- upstream 块中配置 keepalive 32(按并发量调整,通常 16–64)
- 在 location 中启用 proxy_http_version 1.1 和 proxy_set_header Connection ''
- 如后端为 Node.js/Python,默认不保活,需额外设置其 idle timeout > Nginx 的 keepalive_timeout
- 可选:开启 proxy_socket_keepalive on,防中间网络设备主动断连
验证是否真正复用成功
光看配置生效不代表效果落地。需结合工具确认 OPTIONS 是否被拦截、TLS 是否复用、HTTP/2 流是否共用连接。
- 用 curl -I -X OPTIONS https://your.domain/api/test 检查响应头与状态码(应为 204,无 Server: nginx 后还带后端标识)
- 浏览器 DevTools → Network → 查看 OPTIONS 请求的 Protocol 列是否显示 h2,Connection 是否复用(Reused connection)
- 启用 stub_status 或监控 nginx_stub_status 中 Active connections 数变化趋势
- 抓包观察 TLS handshake 是否跳过(ClientHello 中有 session_ticket 或 session_id 复用)











