最直接方式是查看浏览器Network面板响应头是否含Access-Control-Allow-Origin等字段;若缺失,浏览器将拦截响应且控制台报CORS错误。
直接看浏览器开发者工具的 Network 面板里响应头是否包含 Access-Control-Allow-Origin 等字段。这是判断服务端是否开启 CORS 的最直接方式,不是看请求头,而是看响应头。
注意:即使你发出了跨域请求,如果服务端没返回任何 Access-Control-* 头,浏览器就会静默拦截响应体(你 JS 里 fetch().then() 根本不会执行),此时控制台会报类似 Blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present 的错误。
Access-Control-Allow-Origin 是必须项,值可以是具体域名(如 https://a.com)、通配符 *(但不支持带凭证的请求)Credentials(比如 fetch(..., { credentials: 'include' })),则 Access-Control-Allow-Origin 不能为 *,且必须显式声明域名OPTIONS)成功后,浏览器才发真实请求;预检失败时,真实请求根本不会发出绕过浏览器限制,用命令行直接查服务端原始响应头,能排除前端代码干扰,快速定位是服务端没配、配错,还是前端触发了预检但没处理好。
例如检查接口 https://api.example.com/data:
curl -I https://api.example.com/data
观察输出中是否有 Access-Control-Allow-Origin: 行。如果没看到,说明服务端未启用 CORS,前端再怎么配 mode: 'cors' 都无效。
在浏览器控制台也可用 fetch 手动触发并打印 headers:
fetch('https://api.example.com/data', { method: 'GET' })
.then(res => {
console.log('Headers:', Object.fromEntries(res.headers));
});
注意:这个 fetch 必须能成功进入 then,否则说明被 CORS 拦截了——此时你根本拿不到 res.headers,因为浏览器禁止 JS 读取被拦截响应的 header。
这是常见误解:浏览器允许你看到 Network 面板里的完整响应(包括 body 和 headers),但 JS 脚本只能访问“被 CORS 显式授权”的 header 字段。
默认情况下,JS 只能读取以下“简单响应头”:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。其他自定义头(比如 X-Request-ID)或 Set-Cookie,必须由服务端显式通过 Access-Control-Expose-Headers 声明。
Access-Control-Expose-Headers: X-Request-ID, X-RateLimit-Remaining
res.headers.get('X-Request-ID') 返回 null,哪怕 Network 面板里清清楚楚显示着它当请求含自定义 header(如 Authorization)、非简单方法(如 PATCH)、或 Content-Type 不是 application/x-www-form-urlencoded、multipart/form-data、text/plain 之一时,浏览器会先发一个 OPTIONS 请求探路。
此时你要检查两件事:
OPTIONS 请求返回了 200 + 正确的 CORS 头(尤其是 Access-Control-Allow-Methods 和 Access-Control-Allow-Headers)OPTIONS 当作非法方法直接 405 返回,而没做任何 CORS 响应典型错误配置:Nginx 或 API 网关只给 GET/POST 加了 CORS 头,漏掉了 OPTIONS 分支;或者后端框架中间件没覆盖预检路径。
解决办法是确保 OPTIONS 请求也返回相同 CORS 头,且状态码为 200 或 204(不要重定向或 4xx)。