浏览器把跨域请求分两类。简单请求(GET/POST/HEAD,且头部只含 Accept、Content-Type 为 form-urlencoded/text/plain 等安全值)直接发送,由响应头 Access-Control-Allow-Origin 决定放行与否。非简单请求——如 PUT/DELETE 方法、Content-Type: application/json、带自定义头(Authorization 等)——浏览器先发一个 OPTIONS 预检请求,询问服务器是否允许该方法和头;预检通过才发真实请求。

配置要点:服务端需响应 Access-Control-Allow-Origin(允许的源)、Access-Control-Allow-Methods、Access-Control-Allow-Headers,可用 Access-Control-Max-Age 缓存预检结果减少 OPTIONS 次数。常见坑:1)带 Cookie 时需 Access-Control-Allow-Credentials: true,且 Allow-Origin 不能是 * 必须是具体源,前端 fetch 也要 credentials: 'include';2)Allow-Origin 不支持多域名通配,多源场景要在服务端按白名单动态回显 Origin;3)预检失败时报错信息不直观,可用 curl -X OPTIONS 手动验证。追问方向:为什么浏览器要发起预检而服务器不自己拦(历史兼容:保护不理解 CORS 的旧服务器免受非简单请求副作用)、Nginx 层统一处理 OPTIONS 返回 204 的配置。

(约 430 字)