Apache 中 OPTIONS 预检请求变慢是因为默认走完整请求链,解决方法是用 RewriteRule 在 rewrite 阶段直接返回 204,并配合 Header always 设置 CORS 头,同时禁用后端 CORS 预检逻辑。

为什么 OPTIONS 预检请求会变慢
浏览器在发送某些跨域请求(如带 Authorization 头、Content-Type: application/json)前,会先发一个 OPTIONS 请求探路。如果 Apache 没做特殊处理,这个请求会走完整请求链:匹配虚拟主机 → 执行 .htaccess → 进入后端(比如 PHP/Python),再由应用层返回 204。这多出来的几毫秒到几百毫秒,在高频 API 调用下会明显拖慢首屏或表单提交。
用 RewriteRule 直接拦截并响应 OPTIONS
最轻量的解法是让 Apache 在 rewrite 阶段就截住 OPTIONS,不往下传。关键不是“允许跨域”,而是“别让预检进后端”。
- 确保
mod_rewrite已启用:a2enmod rewrite(Debian/Ubuntu)或检查LoadModule rewrite_module - 在虚拟主机配置或
.htaccess中添加:
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ - [R=204,L]注意:- 表示不重写路径,R=204 强制返回空响应体,L 确保终止后续规则。不要用 Redirect 204 —— 它不支持 204 状态码,会退化成 302。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
配合 CORS 头时,Header 指令必须加 always
如果还要在响应里加 Access-Control-Allow-Origin 等头,不能只写 Header set ...。因为 204 响应不经过内容输出阶段,普通 Header 指令会被跳过。
- 正确写法:
Header always set Access-Control-Allow-Origin "*" - 同理,
Access-Control-Allow-Methods、Access-Control-Allow-Headers也都得带always - 若需动态值(如信任特定域名),可用
%{HTTP:Origin}变量 +Header always set组合,但要小心反射漏洞
避免和后端框架的 CORS 中间件冲突
很多框架(如 Express、Django REST Framework)自带 CORS 支持。如果 Apache 已经处理了 OPTIONS,后端再对同一请求做 CORS 预检响应,反而可能出错——比如返回了 200 但没带必要头,或重复设置头导致浏览器拒绝。
- 上线前务必关掉后端的预检自动响应逻辑(例如 Express 的
cors()中设preflightContinue: false) - 用
curl -I -X OPTIONS http://yoursite/api/xxx验证:状态码应为204,且只含你 Apache 显式设置的 CORS 头 - 如果后端必须参与(比如需要鉴权后才允许跨域),那就别用 rewrite 截断,改用
ProxyPassMatch+ 后端统一处理,但性能代价更大
真正容易被忽略的是:rewrite 规则的位置。它必须放在所有可能触发内部重定向(比如 FallbackResource 或 DirectoryIndex)的指令之前,否则 OPTIONS 可能被误导向 index.php。

















