核心是拦截OPTIONS请求不进后端:用RewriteRule在rewrite阶段返回204,并通过Header always set配合<Limit OPTIONS>注入CORS头,避开应用层,延迟压至1毫秒,同时确保Access-Control-Max-Age生效以实现浏览器缓存。

优化 Apache 处理跨域请求的性能损耗,核心不是“加头”,而是让预检(OPTIONS)请求不进后端、不走业务逻辑、不触发 PHP/Python 等应用层处理——把响应压到 1 毫秒级,并让浏览器真正缓存预检结果。
拦截 OPTIONS 请求,在 rewrite 阶段直接返回 204
浏览器每次发复杂请求前都会先发 OPTIONS,如果这个请求落到后端,就会白白消耗数据库连接、中间件栈、鉴权逻辑等资源。必须在 Apache 最早的处理阶段就截断它:
- 启用 mod_rewrite:
a2enmod rewrite并重启服务 - 在虚拟主机或 .htaccess 中添加三行(顺序不可变):
RewriteEngine OnRewriteCond %{REQUEST_METHOD} OPTIONSRewriteRule ^(.*)$ - [R=204,L] - 注意:不能用
Redirect 204,Apache 不支持 204 的重定向,会退化成 302
用 Header always set 注入 CORS 头,确保 OPTIONS 响应完整
普通 Header set 对 204 响应无效,因为 Apache 默认只在内容生成阶段注入头;而 always set 强制在所有响应阶段生效,尤其适用于由内部模块(如 mod_proxy、静态文件处理器)生成的轻量响应:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 必须包裹在
<IfModule mod_headers.c>中,并启用 mod_headers - 必须绑定到 OPTIONS 方法,推荐写法:
<Limit OPTIONS>Header always set Access-Control-Allow-Origin "*"Header always set Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS"Header always set Access-Control-Allow-Headers "Content-Type,Authorization,X-Requested-With"Header always set Access-Control-Max-Age "86400"</Limit> - 若需白名单 Origin,可用
SetEnvIf Origin ^(https?://example\.com)$ ORIGIN_IS_ALLOWED+Header always set Access-Control-Allow-Origin "%{ORIGIN_IS_ALLOWED}e",但禁止反射 Origin 值
统一响应出口,关闭后端的 OPTIONS 处理
Apache 已经响了 OPTIONS,后端再处理同一请求,会导致头重复、状态码冲突(比如 200 vs 204)、甚至鉴权误判:
- Express 用户:确认未启用
cors({ preflightContinue: true }),默认是 false,但检查中间件是否被覆盖 - Django REST Framework 用户:禁用
CorsMiddleware,或在中间件中显式跳过 OPTIONS 方法 - 验证方式:
curl -I -X OPTIONS https://yoursite/api/v1/data,响应应为HTTP/1.1 204 No Content,且只含你 Apache 显式设置的头,无 X-Powered-By、Server 等干扰项
确保 Access-Control-Max-Age 实际生效
设了 86400 不等于浏览器真缓存 24 小时。以下任一不满足,预检都会重发:
- 后续请求的
Origin必须与预检时完全一致(协议、域名、端口全等) - 请求方法、自定义头(如 Authorization)、Content-Type 类型必须与上次预检请求一致
- 中间链路(CDN、反向代理、负载均衡器)不能清洗或覆盖
Access-Control-Max-Age和其他 CORS 头 - 若启用了
Access-Control-Allow-Credentials: true,则Access-Control-Allow-Origin不能为*,必须指定具体域名
不复杂但容易忽略:预检优化的本质是减少网络往返 + 延长缓存窗口,关键动作就两步——Apache 拦截并快速响应,浏览器按规则复用结果。


















