Nginx应在反向代理层拦截并直接返回204响应处理OPTIONS预检请求,避免透传至后端;需按路径精细化配置(如/api/)、动态设置Access-Control-Allow-Origin、禁用缓存、防止响应头重复,并为透传场景设置超时与限流。
OPTIONS预检请求本身不携带业务数据,但若全部透传到后端服务,会带来不必要的计算、日志、鉴权开销,尤其在高并发跨域场景下可能成为性能瓶颈。Nginx完全可以在反向代理层拦截并响应这类请求,避免穿透到上游。
直接在Nginx中返回204响应这是最轻量、最推荐的做法。预检请求只需确认CORS策略是否允许,无需后端参与。Nginx可通过location匹配OPTIONS方法并立即返回,不转发给proxy_pass。
在server或location块中添加:if ($request_method = 'OPTIONS') {add_header Access-Control-Allow-Origin "*";add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE";add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization";add_header Access-Control-Max-Age 1728000;add_header Access-Control-Allow-Credentials true;add_header Content-Type "text/plain; charset=utf-8";add_header Content-Length 0;return 204;}
注意:
if在location内使用是安全的;避免在server级滥用if,防止重写逻辑混乱Access-Control-Allow-Origin值需与业务实际一致(如不能在带Credentials时用*),建议根据Origin头动态设置按路径精细化控制预检行为并非所有接口都需要CORS支持。可针对API路径(如/api/)启用预检拦截,静态资源或管理后台路径则跳过。
用location前缀匹配API路径:location ^~ /api/ {if ($request_method = 'OPTIONS') { ... return 204; }proxy_pass http://backend;}对不需要跨域的路径(如/assets/或/health),不配置OPTIONS拦截,保持默认透传或直接拒绝可结合map指令统一管理跨域白名单,提升可维护性避免重复响应头和缓存干扰后端若也返回CORS头,与Nginx叠加可能导致冲突(如多个Access-Control-Allow-Origin);同时,预检响应应禁止缓存,否则浏览器可能复用过期策略。
确保后端在收到OPTIONS请求时不输出任何响应体,并且不设置CORS相关header(或明确关闭)
Nginx中显式添加:
add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";add_header Pragma "no-cache";add_header Expires "0";用curl -v -X OPTIONS验证响应头是否干净、无重复、状态码为204配合后端健康检查做降级兜底极少数场景(如需后端动态生成CORS策略)仍需透传OPTIONS。此时应限制其频率,并设置超时与重试策略,避免因后端延迟拖垮Nginx。
启用proxy_next_upstream:当后端超时或5xx时快速切换节点proxy_next_upstream error timeout http_500 http_502 http_503;缩短OPTIONS专属超时:location /api/ {if ($request_method = 'OPTIONS') {proxy_read_timeout 2;proxy_connect_timeout 1;proxy_send_timeout 1;proxy_pass http://backend;}}搭配limit_req限制单位时间OPTIONS请求数,防恶意探测
