OPTIONS请求需优先拦截并返回204,再对剩余请求限流;可单独为OPTIONS配置限速区(如10r/m),配合Access-Control-Max-Age缓存预检结果,并与主API限流协同防护。

OPTIONS 请求本身不携带业务数据,但恶意扫描器或攻击脚本常高频发送 OPTIONS 预检请求,消耗连接、CPU 和日志资源。Nginx 默认不对其限流,必须显式配置才能防护——关键不是“能不能限”,而是“怎么限才既防攻击又不影响合法跨域”。
先拦截再限速:OPTIONS 必须单独处理
浏览器预检是标准行为,但攻击者会伪造大量 OPTIONS 请求试探接口或耗尽资源。不能让它们进入 limit_req 的通用队列,否则会挤占正常请求配额。正确做法是:在 location 块中优先判断并终止合法 OPTIONS,再对剩余请求统一限流。
- 用 if 判断请求方法:
if ($request_method = 'OPTIONS') { return 204; }—— 立即响应,不走后续逻辑,零开销 - 这个 return 必须放在 limit_req 指令之前,否则限流模块仍会统计 OPTIONS 请求
- 返回 204 而非 200,语义更准确,且不带响应体,节省带宽
对真实 OPTIONS 请求做轻量限速(可选但推荐)
有些场景(如 API 网关需暴露接口能力)允许 OPTIONS 被外部探测,这时可对 OPTIONS 单独限速,避免被刷。
- 定义专用限速区:
limit_req_zone $binary_remote_addr zone=options:5m rate=10r/m; - 在匹配 OPTIONS 的 location 中启用:
limit_req zone=options burst=3 nodelay; - rate 设为每分钟 10 次足够覆盖人工调试,burst 控制在 3~5,防止短时扫描洪峰
- 务必配合
add_header Access-Control-Max-Age 1728000 always;,让浏览器缓存预检结果,大幅降低重复 OPTIONS 量
避免 CORS 头干扰限流逻辑
CORS 响应头(如 Access-Control-Allow-Origin)由 Nginx 注入,不影响限流判断,但配置不当会导致限流失效或误判。
- 所有 CORS 头必须用
add_header在 server 或 location 块中声明,不要依赖后端返回 - 若允许多个域名,用 map 指令白名单匹配 Origin,避免动态设置导致缓存失效
- 禁止在 if 块中写 add_header —— Nginx 不支持,头会丢失
- 检查最终响应是否只有一组 CORS 头,重复头会让浏览器拒绝跨域请求
与整体限流策略协同
OPTIONS 是入口探针,真正风险在于它背后隐藏的恶意 POST/GET 攻击。所以 OPTIONS 限速只是第一道观察哨。
- 主 API location(如 /api/)仍需配置独立的 limit_req,按 IP 或 URI 限速,例如:
limit_req_zone $binary_remote_addr zone=api:10m rate=20r/s; - 对登录、密码重置等敏感路径,叠加 limit_conn 限制并发连接数,防绕过限速
- 开启
$limit_req_status日志字段,监控 rejected/delayed 的 OPTIONS 请求比例,异常升高即提示扫描行为


















