如何优化 CORS 预检请求缓存 Access-Control-Max-Age 配置多少合适

文章导读
生产环境稳定接口推荐设置 Access-Control-Max-Age 为 86400 秒(24 小时),频繁变更的 API 建议设置为 1800 秒至 3600 秒。浏览器对最大缓存时间的支持上限为 24 小时,超过该值的配置将被忽略。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
  7. G 参考来源
A A

生产环境稳定接口推荐设置 Access-Control-Max-Age 为 86400 秒(24 小时),频繁变更的 API 建议设置为 1800 秒至 3600 秒。浏览器对最大缓存时间的支持上限为 24 小时,超过该值的配置将被忽略。

先说结论:Access-Control-Max-Age 配置需根据接口变更频率决定,生产环境稳定接口可设为最大值 86400 秒。

  • 适合:跨域请求频繁的 Web 应用、移动端 API 服务、静态资源跨域加载场景
  • 先做:确认后端框架默认值,FastAPI 默认为 600 秒,Tomcat 常见默认为 1800 秒
  • 再验证:通过浏览器开发者工具 Network 面板观察 OPTIONS 请求是否减少

命令速用版

不同后端框架设置 Access-Control-Max-Age 的配置片段如下,直接替换对应中间件或过滤器配置即可。

# FastAPI (Python)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://app.example.com"],
    max_age=86400  # 24 小时
)

# Nginx (lua/cors.conf)
add_header 'Access-Control-Max-Age' '86400';

# Tomcat (web.xml CorsFilter)
<init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>86400</param-value>
</init-param>

# Node.js (cors middleware)
app.use(cors({
    maxAge: 86400
}));

为什么会这样

浏览器发送跨域非简单请求前会先发 OPTIONS 预检请求,Access-Control-Max-Age 告诉浏览器缓存该预检结果多久。

设置该参数后,在缓存有效期内,浏览器对相同来源、相同方法、相同请求头的跨域请求不再发送 OPTIONS 预检,直接发送实际请求。这能减少网络往返次数,降低服务器处理预检请求的负载,尤其在移动端弱网环境下能显著降低延迟。公开资料中没有看到可靠的量化数据表明具体减少多少毫秒,但机制上是消除了重复预检的网络开销。

分步处理

按以下步骤配置并生效 CORS 预检缓存。

步骤 1:确认当前框架默认值
检查后端代码或文档。FastAPI 的 CORSMiddleware 默认 max_age 为 600 秒。Tomcat 的 CorsFilter 默认 cors.preflight.maxage 常见为 1800 秒。若默认值满足需求可跳过后续步骤。

步骤 2:修改配置参数
根据接口稳定性选择数值。生产环境稳定接口设置 86400 秒。频繁变更的 API 设置 1800 秒或 3600 秒。开发环境调试可设置 0 或 3600 秒。

如何优化 CORS 预检请求缓存 Access-Control-Max-Age 配置多少合适

步骤 3:重启服务
修改配置文件或代码后,重启后端服务或 reload Nginx 配置使新 Header 生效。

步骤 4:清理客户端缓存
配置变更前浏览器可能已缓存旧策略。测试前需在浏览器开发者工具中勾选"Disable cache"或清除浏览器缓存,确保获取最新响应头。

怎么验证是否生效

通过浏览器开发者工具确认响应头和请求频率。

检查响应头:打开浏览器开发者工具 Network 面板,发起跨域请求,查看 OPTIONS 请求的 Response Headers。确认存在 Access-Control-Max-Age 且数值与配置一致。

检查请求频率:在缓存有效期内(如设置 86400 秒),连续发起相同条件的跨域请求。首次请求应有 OPTIONS 预检,后续请求应直接发送 GET/POST 等实际请求,不再出现 OPTIONS 请求。

检查缓存失效:等待超过设定时间或更改请求头/方法,浏览器应重新发送 OPTIONS 预检请求。

常见坑

配置 Access-Control-Max-Age 时需注意以下边界和风险。

超过 24 小时无效:根据 W3C CORS 规范,浏览器对 max-age 的支持上限为 24 小时(86400 秒)。配置超过此值(如 604800 秒)将被浏览器忽略,仍按默认策略处理。

如何优化 CORS 预检请求缓存 Access-Control-Max-Age 配置多少合适

动态 Origin 问题:若 Access-Control-Allow-Origin 设置为动态匹配(如反射请求头),部分浏览器可能不缓存预检结果,导致 Max-Age 失效。建议生产环境使用明确的白名单域名。

凭证模式限制:当 Access-Control-Allow-Credentials 为 true 时,部分浏览器对预检缓存的处理策略可能更严格,需实测验证。

默认值差异:不同框架默认值不同。FastAPI 默认 600 秒,Tomcat 默认常见 1800 秒。迁移项目时需注意默认行为变化。

常见问题

Access-Control-Max-Age 设置为 0 是什么意思?

设置为 0 表示浏览器不缓存预检请求结果,每次跨域请求都会发送 OPTIONS 预检。适合开发环境调试 CORS 策略。

为什么配置了 86400 秒还是每次都发 OPTIONS 请求?

可能原因包括请求头或方法发生变化导致缓存失效、Origin 动态变化导致不缓存、或浏览器隐私模式禁用了缓存。需检查请求一致性。

移动端 WebView 支持该缓存机制吗?

主流移动端 WebView 基于 Chromium 或 WebKit 内核,支持 Access-Control-Max-Age 缓存机制。配置生效后能减少移动端弱网下的请求延迟。

FastAPI 默认缓存时间是多少?

FastAPI 的 CORSMiddleware 默认 max_age 参数值为 600 秒,即 10 分钟。

参考来源

  • FastAPI 跨域预检:Access-Control-Max-Age 缓存优化完全指南
  • Tomcat 中的静态资源 CORS 预检请求缓存:max-age 配置
  • 突破前端跨域瓶颈:ngx-admin 中 Access-Control-Max-Age 缓存策略全解析
  • 终极指南:Tomcat 中静态资源 CORS 与预检请求缓存配置详解
  • CORS 中间件性能优化:如何减少不必要的预检请求
  • Nginx Proxy Manager CORS 预检请求优化:缓存与 OPTIONS 请求处理