--- title: "CORS 允许的请求头配置" date: 2026-03-01 lastmod: 2026-03-01 description: "http.cors.allow-headers 配置项用于指定在跨域请求中允许的 HTTP 请求头列表。" tags: ["HTTP", "CORS", "跨域", "请求头"] summary: "配置项作用 # http.cors.allow-headers 配置项用于指定在跨域资源共享(CORS)请求中允许浏览器发送的自定义 HTTP 请求头列表。 当浏览器发送跨域请求时,如果请求包含自定义头部,服务器需要在响应的 Access-Control-Allow-Headers 中明确声明允许这些头部,浏览器才会允许请求通过。 配置项属性 # 配置路径: http.cors.allow-headers 数据类型: String(逗号分隔的字符串列表) 默认值: "X-Requested-With,Content-Type,Content-Length" 是否可选: 是 作用域: NodeScope(节点级别) 配置项详解 # 工作机制 # CORS 预检请求流程 浏览器发送实际请求前 │ ↓ 发送 OPTIONS 预检请求 │ ↓ 包含请求的头部信息 Access-Control-Request-Headers: X-Auth-Token,Custom-Header │ ↓ 服务器检查 allow-headers 配置 │ ├──────── 所有头部都在允许列表中 ✅ │ ↓ │ 返回成功响应 │ ↓ │ Access-Control-Allow-Headers: │ X-Requested-With,Content-Type,X-Auth-Token,Custom-Header │ ↓ │ 浏览器发送实际请求 │ └──────── 有头部不在允许列表中 ❌ ↓ 返回错误响应 ↓ 浏览器阻止实际请求 简单请求 vs 预检请求 # 简单请求(无需预检): - 使用默认的 CORS 安全头部 - GET、HEAD、POST 方法 - Content-Type: application/x-www-form-urlencoded - multipart/form-data、text/plain 直接发送请求,不需要预检 非简单请求(需要预检): - 使用自定义头部 - PUT、DELETE 方法 - Content-Type: application/json 1." --- ## 配置项作用 `http.cors.allow-headers` 配置项用于指定**在跨域资源共享(CORS)请求中允许浏览器发送的自定义 HTTP 请求头列表**。 当浏览器发送跨域请求时,如果请求包含自定义头部,服务器需要在响应的 `Access-Control-Allow-Headers` 中明确声明允许这些头部,浏览器才会允许请求通过。 ## 配置项属性 - **配置路径**: `http.cors.allow-headers` - **数据类型**: `String`(逗号分隔的字符串列表) - **默认值**: `"X-Requested-With,Content-Type,Content-Length"` - **是否可选**: 是 - **作用域**: NodeScope(节点级别) ## 配置项详解 ## 工作机制 ``` CORS 预检请求流程 浏览器发送实际请求前 │ ↓ 发送 OPTIONS 预检请求 │ ↓ 包含请求的头部信息 Access-Control-Request-Headers: X-Auth-Token,Custom-Header │ ↓ 服务器检查 allow-headers 配置 │ ├──────── 所有头部都在允许列表中 ✅ │ ↓ │ 返回成功响应 │ ↓ │ Access-Control-Allow-Headers: │ X-Requested-With,Content-Type,X-Auth-Token,Custom-Header │ ↓ │ 浏览器发送实际请求 │ └──────── 有头部不在允许列表中 ❌ ↓ 返回错误响应 ↓ 浏览器阻止实际请求 ``` ## 简单请求 vs 预检请求 ``` 简单请求(无需预检): - 使用默认的 CORS 安全头部 - GET、HEAD、POST 方法 - Content-Type: application/x-www-form-urlencoded - multipart/form-data、text/plain 直接发送请求,不需要预检 非简单请求(需要预检): - 使用自定义头部 - PUT、DELETE 方法 - Content-Type: application/json 1. 先发送 OPTIONS 预检请求 2. 服务器返回允许的头部 3. 浏览器再发送实际请求 ``` ## 默认头部说明 ``` 默认允许的头部 X-Requested-With: - 作用: 标识 AJAX 请求 - 常见值: XMLHttpRequest - 用途: 服务器区分普通请求和 AJAX 请求 Content-Type: - 作用: 指定请求内容类型 - 常见值: application/json, text/plain - 用途: 告知服务器如何解析请求体 Content-Length: - 作用: 请求体的字节长度 - 常见值: 数字 - 用途: 服务器用于读取完整的请求体 ``` ## 配置建议 ## 默认配置(简单场景) ```yaml http: cors: enabled: true allow-origin: "*" allow-headers: "X-Requested-With,Content-Type,Content-Length" # 默认值 ``` **建议**: 保持默认值。适用于标准的 AJAX 请求。 ## 需要 JSON 请求体 ```yaml http: cors: enabled: true allow-origin: "*" allow-headers: "X-Requested-With,Content-Type,Content-Length,Accept" ``` **建议**: 添加 `Accept` 头。当需要发送 JSON 请求体时使用。 ## 需要 JWT 认证 ```yaml http: cors: enabled: true allow-origin: "https://example.com" allow-headers: "X-Requested-With,Content-Type,Content-Length,Authorization" allow-credentials: true ``` **建议**: 添加 `Authorization` 头。当使用 JWT Token 认证时使用。 ## 完整配置(生产环境) ```yaml http: cors: enabled: true allow-origin: "https://app.example.com" allow-headers: "X-Requested-With,Content-Type,Content-Length,Authorization,Accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers" allow-credentials: true allow-methods: "GET,POST,PUT,DELETE,OPTIONS,HEAD" max-age: 3600 ``` **建议**: 包含所有必要的头部。生产环境的完整配置。 ## 代码示例 ## easysearch.yml 基础配置 ```yaml http: cors: enabled: true allow-origin: "*" allow-headers: "X-Requested-With,Content-Type,Content-Length" ``` ## 开发环境配置 ```yaml http: cors: enabled: true allow-origin: "http://localhost:3000" allow-headers: "X-Requested-With,Content-Type,Content-Length,Authorization,X-Auth-Token" ``` ## 多应用支持配置 ```yaml http: cors: enabled: true allow-origin: "https://app1.example.com,https://app2.example.com" allow-headers: "X-Requested-With,Content-Type,Content-Length,Authorization,X-API-Key,X-Client-Version" ``` ## 自定义认证头配置 ```yaml http: cors: enabled: true allow-origin: "https://dashboard.example.com" allow-headers: "X-Requested-With,Content-Type,Content-Length,X-Custom-Auth,X-Session-ID" ``` ## 相关配置 | 配置项 | 作用 | 默认值 | |--------|------|--------| | `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.allow-credentials` | 是否允许凭证 | false | | `http.cors.max-age` | 预检请求缓存时间 | 1728000 | ## 前端请求示例 ## 带 Authorization 头的请求 ```javascript fetch('https://easysearch.example.com/_search', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token }, body: JSON.stringify({ query: { match_all: {} } }) }) ``` **需要配置**: `Authorization` ## 带自定义 API Key 的请求 ```javascript axios.get('https://easysearch.example.com/_cluster/health', { headers: { 'X-API-Key': 'your-api-key' } }) ``` **需要配置**: `X-API-Key` ## 带自定义客户端信息的请求 ```javascript fetch('https://easysearch.example.com/_cat/indices', { headers: { 'Content-Type': 'application/json', 'X-Client-Version': '1.0.0', 'X-Session-ID': 'session-123' } }) ``` **需要配置**: `X-Client-Version`, `X-Session-ID` ## 常见请求头说明 ## 标准请求头 ``` Content-Type: - application/json - application/x-www-form-urlencoded - text/plain Accept: - application/json - application/xml - text/html Authorization: - Bearer - Basic Origin: - https://example.com ``` ## 自定义请求头 ``` 认证相关: - X-Auth-Token - X-API-Key - X-Session-ID 客户端信息: - X-Client-Version - X-Device-ID - X-Request-ID 业务相关: - X-Tenant-ID - X-Organization-ID - X-Custom-Header ``` ## 使用场景 ## 推荐使用默认配置的场景 - **简单查询**: 只需要基本的 CRUD 操作 - **公开 API**: 不需要认证的数据接口 - **标准 AJAX**: 使用标准的 XMLHttpRequest 或 Fetch ## 推荐添加 Authorization 的场景 - **JWT 认证**: 使用 Bearer Token 认证 - **OAuth 2.0**: 使用 OAuth 认证流程 - **Basic Auth**: 使用 HTTP 基本认证 ## 推荐添加自定义头的场景 - **API Key**: 使用自定义 API Key 认证 - **多租户**: 需要传递租户信息 - **会话管理**: 需要传递会话 ID - **客户端追踪**: 需要传递客户端版本或设备信息 ## 预检请求示例 ``` 浏览器发送 OPTIONS 请求: OPTIONS /_search HTTP/1.1 Host: easysearch.example.com Origin: https://app.example.com Access-Control-Request-Method: POST Access-Control-Request-Headers: Content-Type,Authorization 服务器返回响应: HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://app.example.com Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS Access-Control-Allow-Headers: X-Requested-With,Content-Type,Content-Length,Authorization Access-Control-Max-Age: 3600 浏览器检查响应后发送实际请求: POST /_search HTTP/1.1 Host: easysearch.example.com Origin: https://app.example.com Content-Type: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... { "query": { "match_all": {} } } ``` ## 常见问题排查 ## 问题 1: 请求被 CORS 阻止 ``` 错误信息: Request header field X-Custom-Header is not allowed by Access-Control-Allow-Headers 原因: allow-headers 配置中没有包含 X-Custom-Header 解决: http.cors.allow-headers: "X-Requested-With,Content-Type,Content-Length,X-Custom-Header" ``` ## 问题 2: Authorization 头未生效 ``` 现象: 前端设置了 Authorization 头,但服务器没有收到认证信息 原因: 1. allow-headers 中没有包含 Authorization 2. 浏览器在预检请求中被拒绝 解决: http.cors.allow-headers: "X-Requested-With,Content-Type,Content-Length,Authorization" http.cors.allow-credentials: true ``` ## 问题 3: 大量预检请求 ``` 现象: 每次请求都先发送 OPTIONS 预检请求 原因: max-age 设置过小或未设置 解决: http.cors.max-age: 3600 # 缓存 1 小时 ``` ## 注意事项 1. **必须启用 CORS**: 只有在 `http.cors.enabled: true` 时,此配置才生效。 2. **大小写不敏感**: 头部名称不区分大小写,但建议使用标准的大写形式。 3. **逗号分隔**: 多个头部使用逗号分隔,不要有空格或使用其他分隔符。 4. **预检请求**: 任何不在默认列表中的自定义头部都会触发预检请求。 5. **与 allow-credentials 配合**: 如果启用了凭证,需要特别注意安全配置。 6. **性能优化**: 设置合理的 `max-age` 可以减少预检请求次数。 7. **最小权限原则**: 只添加业务必需的头部,不要添加所有可能的头部。 8. **调试建议**: 使用浏览器开发者工具查看 Network 面板中的预检请求。 9. **通配符限制**: 预检请求的响应中不能使用 `*` 作为 `allow-headers` 的值。 10. **动态更新**: 此配置支持动态更新,修改后立即生效。