什么? 接口跨域 , 设置了 Access-Control-Allow-Origin:* 还是不行??

1,138 阅读2分钟

CORS跨域请求头错误解决方案

明明设置了

Access-Control-Allow-Origin:*
Access-Control-Allow-Headers:*
Access-Control-Allow-Methods:*
Access-Control-Allow-Credentials: true

我都所有的都设置了通配符 * 了, 什么还不行!!!

案例报错提示:

has been blocked by CORS policy: 
Request header field accept-lang is not allowed by Access-Control-Allow-Headers in preflight response.

这是提示了accept-lang 不允许 在预请求中

怎么解决这个问题呢??

根据CORS规范,Access-Control-Allow-Headers允许服务器指定哪些请求头可以被允许。但通配符*在这里有特定条件。比如,当请求包含认证信息(如cookies或Authorization头)时,使用*是不被允许的。这时候服务器必须明确列出允许的头部,而不能用通配符。

另外,可能后端配置有误,比如虽然设置了*,但没有正确处理预检请求(OPTIONS),或者服务器没有正确返回这个头部。需要说明浏览器在预检请求时会检查这些头部,如果服务器响应不正确,就会阻止请求。

1. CORS 规范的限制

根据 CORS 规范,Access-Control-Allow-Headers: * 仅在以下两种情况下有效:

  • 请求不携带身份凭证(如 cookiesAuthorization 头)。
  • 服务器未明确列出其他特定头字段(如 Content-Type)。

如果请求需要身份验证(比如携带 cookies),或者服务器返回了其他明确的头字段(如 Content-Type),浏览器会直接忽略 * 通配符,导致请求失败。

2. 预检请求(Preflight Request)的特殊性

当请求包含自定义头(如 accept-lang)时,浏览器会先发送一个 OPTIONS 预检请求,询问服务器是否允许该请求。此时:

  • 如果服务器返回 Access-Control-Allow-Headers: *,但请求需要身份验证(如 cookies),浏览器会拒绝 * 的模糊授权。
  • 必须显式列出允许的请求头(如 accept-lang),否则预检失败。

正确解决方案

明确 请求头, 不能使用*

# Nginx 配置
add_header Access-Control-Allow-Headers "accept-lang,  xxxx";

为什么不能偷懒用 *

  • 场景限制:仅适用于简单请求且无需身份验证的极少数情况。
  • 规范约束:CORS 设计初衷是保护用户安全,强制开发者明确声明权限。
  • 未来兼容性:浏览器对 * 的支持会逐步弱化。