← 中文资源

简体中文版本

CORS 预检失败 — 浏览器阻止请求

通过检查 OPTIONS 预检请求与响应头,定位来源、方法、请求头或凭据配置问题,并给出可验证的修复。

阅读英文原文

症状

控制台报 “Response to preflight request doesn’t pass access control check”;Network 面板只有 OPTIONS 请求,返回 404、405 或 500,真正的请求没有发出;curl 能成功而浏览器失败,说明是浏览器强制执行的 CORS 检查。

诊断

curl -i -X OPTIONS https://api.example.com/orders \
  -H 'Origin: https://app.example.com' \
  -H 'Access-Control-Request-Method: POST' \
  -H 'Access-Control-Request-Headers: content-type'

检查状态码与响应头:2xx 但缺少 Access-Control-Allow-Origin 仍会失败;404/405 表示 OPTIONS 没有被路由。再确认允许的来源与请求来源完全一致(协议、主机、端口),并检查浏览器 Network 面板中预检的详细信息。

根因

浏览器在发送某些跨源请求前先发送 OPTIONS,并要求响应明确允许来源、方法和请求头。缺少任一必需头或 OPTIONS 路由失败,浏览器就会在真正请求发出前阻止它。

修复

显式处理 OPTIONS,返回 204,并设置精确的 Access-Control-Allow-Origin、所需的 methods 与 headers、Vary: Origin;涉及 Cookie 时使用精确来源与 Access-Control-Allow-Credentials。

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: content-type
Vary: Origin

验证

重新执行预检,确认 204 与预期头;在浏览器中确认真实 POST 成功;再测试一个未授权来源,确认仍被阻止。不要为了消除错误而反射所有来源或允许 null。

常见陷阱

* 不能与凭据同时使用;代理可能剥离头;很多浏览器不允许预检发生重定向。应检查最终响应,而不只是第一跳。