17370845950

HTML5跨域资源共享怎么识别_CORS头信息识别方法【跨域】
最直接方式是查看浏览器Network面板响应头是否含Access-Control-Allow-Origin等字段;若缺失,浏览器将拦截响应且控制台报CORS错误。

怎么确认服务器返回了 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)成功后,浏览器才发真实请求;预检失败时,真实请求根本不会发出

如何用 curl 或浏览器控制台快速验证 CORS 响应头

绕过浏览器限制,用命令行直接查服务端原始响应头,能排除前端代码干扰,快速定位是服务端没配、配错,还是前端触发了预检但没处理好。

例如检查接口 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。

为什么有时候能看到响应体却读不到 header

这是常见误解:浏览器允许你看到 Network 面板里的完整响应(包括 body 和 headers),但 JS 脚本只能访问“被 CORS 显式授权”的 header 字段。

默认情况下,JS 只能读取以下“简单响应头”:Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma。其他自定义头(比如 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 面板里清清楚楚显示着它
  • 这个字段不影响跨域请求能否发出,只影响 JS 能否读取特定 header

预检请求(OPTIONS)失败时怎么排查

当请求含自定义 header(如 Authorization)、非简单方法(如 PATCH)、或 Content-Type 不是 application/x-www-form-urlencodedmultipart/form-datatext/plain 之一时,浏览器会先发一个 OPTIONS 请求探路。

此时你要检查两件事:

  • 服务端是否对 OPTIONS 请求返回了 200 + 正确的 CORS 头(尤其是 Access-Control-Allow-MethodsAccess-Control-Allow-Headers
  • 服务端是否把 OPTIONS 当作非法方法直接 405 返回,而没做任何 CORS 响应

典型错误配置:Nginx 或 API 网关只给 GET/POST 加了 CORS 头,漏掉了 OPTIONS 分支;或者后端框架中间件没覆盖预检路径。

解决办法是确保 OPTIONS 请求也返回相同 CORS 头,且状态码为 200 或 204(不要重定向或 4xx)。