--- title: "CORS 预检请求缓存时间配置" date: 2026-03-17 lastmod: 2026-03-17 description: "http.cors.max-age 配置项用于控制 CORS 预检请求结果在浏览器中的缓存时间。" tags: ["HTTP", "CORS", "跨域", "性能优化"] summary: "配置项作用 # http.cors.max-age 配置项用于控制CORS 预检请求(Preflight Request)的结果在浏览器中的缓存时间。 当浏览器发送跨域请求前,对于非简单请求(如 PUT、DELETE 或带有自定义头的请求),浏览器会先发送一个 OPTIONS 预检请求。max-age 指定了这个预检响应可以被缓存多长时间。 配置项属性 # 配置路径: http.cors.max-age 数据类型: Integer(整数,单位:秒) 默认值: 1728000(20天) 最小值: 0(不缓存) 是否可选: 是 作用域: NodeScope(节点级别) 配置项详解 # 工作机制 # CORS 预检请求缓存流程 首次发送 PUT 请求 │ ↓ 浏览器发送 OPTIONS 预检请求 │ ↓ 服务器返回响应 Access-Control-Max-Age: 1728000 │ ↓ 浏览器缓存预检结果 │ ↓ 在 20 天内再次发送 PUT 请求 │ ↓ 直接发送实际请求(跳过预检)✅ │ ↓ 20 天后再次发送 PUT 请求 │ ↓ 重新发送 OPTIONS 预检请求 缓存效果对比 # 无缓存(max-age = 0): 每次请求: PUT /index/_doc/1 ↓ OPTIONS 预检(网络往返) ↓ PUT 实际请求(网络往返) 总耗时: 2 × 网络延迟 有缓存(max-age = 1728000): 首次请求: PUT /index/_doc/1 ↓ OPTIONS 预检(网络往返) ↓ PUT 实际请求(网络往返) 后续 20 天内的请求: PUT /index/_doc/1 ↓ PUT 实际请求(网络往返) 总耗时: 1 × 网络延迟(节省 50%) 预检请求响应头 # 预检请求响应示例: HTTP/1." --- ## 配置项作用 `http.cors.max-age` 配置项用于控制**CORS 预检请求(Preflight Request)的结果在浏览器中的缓存时间**。 当浏览器发送跨域请求前,对于非简单请求(如 PUT、DELETE 或带有自定义头的请求),浏览器会先发送一个 OPTIONS 预检请求。`max-age` 指定了这个预检响应可以被缓存多长时间。 ## 配置项属性 - **配置路径**: `http.cors.max-age` - **数据类型**: `Integer`(整数,单位:秒) - **默认值**: `1728000`(20天) - **最小值**: `0`(不缓存) - **是否可选**: 是 - **作用域**: NodeScope(节点级别) ## 配置项详解 ## 工作机制 ``` CORS 预检请求缓存流程 首次发送 PUT 请求 │ ↓ 浏览器发送 OPTIONS 预检请求 │ ↓ 服务器返回响应 Access-Control-Max-Age: 1728000 │ ↓ 浏览器缓存预检结果 │ ↓ 在 20 天内再次发送 PUT 请求 │ ↓ 直接发送实际请求(跳过预检)✅ │ ↓ 20 天后再次发送 PUT 请求 │ ↓ 重新发送 OPTIONS 预检请求 ``` ## 缓存效果对比 ``` 无缓存(max-age = 0): 每次请求: PUT /index/_doc/1 ↓ OPTIONS 预检(网络往返) ↓ PUT 实际请求(网络往返) 总耗时: 2 × 网络延迟 有缓存(max-age = 1728000): 首次请求: PUT /index/_doc/1 ↓ OPTIONS 预检(网络往返) ↓ PUT 实际请求(网络往返) 后续 20 天内的请求: PUT /index/_doc/1 ↓ PUT 实际请求(网络往返) 总耗时: 1 × 网络延迟(节省 50%) ``` ## 预检请求响应头 ``` 预检请求响应示例: HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: GET, POST, PUT, DELETE Access-Control-Allow-Headers: Content-Type, Authorization Access-Control-Max-Age: 1728000 Access-Control-Allow-Credentials: true 关键响应头: Access-Control-Max-Age: 1728000 ↓ 浏览器缓存此预检结果 1728000 秒(20 天) ``` ## 配置建议 ## 生产环境(默认) ```yaml http: cors: enabled: true allow-origin: "*" max-age: 1728000 # 默认值(20 天) ``` **建议**: 保持默认值。适用于大多数生产环境,有效减少预检请求。 ## 高频访问场景 ```yaml http: cors: enabled: true allow-origin: "https://app.example.com" max-age: 604800 # 7 天 ``` **建议**: 设置为 7-30 天。当应用需要频繁调用跨域 API 时使用。 ## 开发调试环境 ```yaml http: cors: enabled: true allow-origin: "http://localhost:3000" max-age: 3600 # 1 小时 ``` **建议**: 设置为较短时间(1-24 小时)。开发时配置可能经常变化。 ## 高安全要求 ```yaml http: cors: enabled: true allow-origin: "https://app.example.com" max-age: 600 # 10 分钟 ``` **建议**: 设置为较短时间(5-30 分钟)。当需要快速响应配置变化时使用。 ## 代码示例 ## easysearch.yml 基础配置 ```yaml http: cors: enabled: true allow-origin: "*" max-age: 1728000 ``` ## 完整 CORS 配置 ```yaml http: cors: enabled: true allow-origin: "https://app.example.com" allow-methods: "OPTIONS,HEAD,GET,POST,PUT,DELETE" allow-headers: "Content-Type,Authorization" allow-credentials: true max-age: 86400 # 1 天 ``` ## 开发环境配置 ```yaml http: cors: enabled: true allow-origin: "http://localhost:3000,http://localhost:8080" allow-methods: "GET,POST,PUT,DELETE" allow-headers: "Content-Type" max-age: 3600 # 1 小时 ``` ## 相关配置 | 配置项 | 作用 | 默认值 | |--------|------|--------| | `http.cors.enabled` | 是否启用 CORS | false | | `http.cors.allow-origin` | 允许的来源域名 | - | | `http.cors.allow-methods` | 允许的 HTTP 方法 | OPTIONS,HEAD,GET,POST,PUT,DELETE | | `http.cors.allow-headers` | 允许的请求头 | X-Requested-With,Content-Type,Content-Length | | `http.cors.max-age` | 预检请求缓存时间 | 1728000 | ## 缓存时间参考 ## 不同场景的推荐时间 ``` 静态应用(配置很少变化): max-age: 604800 # 7 天 优点: 最大限度减少预检请求 动态应用(配置可能变化): max-age: 86400 # 1 天 优点: 平衡性能和灵活性 开发环境(配置经常变化): max-age: 3600 # 1 小时 优点: 快速反映配置变化 高安全要求(需要严格控制): max-age: 600 # 10 分钟 优点: 配置变化快速生效 ``` ## 浏览器限制 ``` 不同浏览器的最大缓存时间限制: Chrome/Chromium: - 最大值: 600 秒(10 分钟) - 超过限制的值会被截断 Firefox: - 最大值: 86400 秒(24 小时) - 超过限制的值会被截断 Safari: - 最大值: 600 秒(10 分钟) - 超过限制的值会被截断 实际生效时间: 取服务器配置值和浏览器限制值的较小值 ``` ## 性能影响分析 ## 请求次数对比 ``` 假设应用每 10 秒发送一次 PUT 请求 max-age = 0(无缓存): 1 小时内 = 360 次请求 = 360 次预检 + 360 次实际请求 = 720 次网络往返 max-age = 3600(1 小时): 1 小时内 = 360 次请求 = 1 次预检 + 360 次实际请求 = 361 次网络往返 节省: 359 次预检请求(49.9%) max-age = 1728000(20 天): 假设应用运行 1 天 = 8640 次请求 = 1 次预检 + 8640 次实际请求 = 8641 次网络往返 节省: 8639 次预检请求(99.9%) ``` ## 使用场景 ## 推荐使用长缓存时间的场景 - **生产环境**: 配置稳定,很少变化 - **高频访问**: 应用需要频繁调用跨域 API - **移动应用**: 网络延迟较高,需要减少请求 - **性能优化**: 追求最佳性能表现 ## 推荐使用短缓存时间的场景 - **开发环境**: 配置可能经常调整 - **测试环境**: 需要快速验证配置变化 - **多环境部署**: 可能在不同环境间切换 - **高安全要求**: 需要严格控制跨域访问 ## 缓存失效 ``` 预检缓存失效的情况 1. 缓存时间到期 max-age 的时间到了 ↓ 下次请求重新预检 2. 浏览器关闭 某些浏览器在关闭时清除缓存 ↓ 重新打开后重新预检 3. 清除浏览器数据 用户手动清除缓存 ↓ 下次请求重新预检 4. 配置变化 服务器 CORS 配置变化 ↓ 等待缓存到期后生效 ``` ## 注意事项 1. **浏览器限制**: 浏览器对 `max-age` 有内部上限,超过上限的值会被截断。 2. **配置变化延迟**: 增加缓存时间会导致配置变更延迟生效。 3. **与安全性的平衡**: 缓存时间越长,性能越好,但配置变化的响应越慢。 4. **动态更新**: 此配置支持动态更新,修改后立即生效(但已有缓存不会立即清除)。 5. **清除缓存**: 无法主动清除浏览器中的预检缓存。 6. **不同浏览器**: 不同浏览器对 `max-age` 的处理可能不同。 7. **调试建议**: 调试时可以设置较小的值,方便观察预检请求。 8. **与 CDN 配合**: 如果使用 CDN,需要确保 CORS 头部正确传递。 9. **监控建议**: 监控预检请求的频率,评估缓存效果。 10. **性能测试**: 在生产环境部署前,测试不同缓存时间对性能的影响。