thinkphp跨域预检失败本质是options请求未被正确拦截与响应:需确保think\middleware\cors::class严格注册且置于middleware.php数组最前,动态校验origin白名单、显式声明allowheaders字段,并配置nginx透传origin头及拦截options返回204。

ThinkPHP接口跨域预检失败,本质是浏览器发的 OPTIONS 请求没被正确响应——不是前端写错了,而是后端没接住、没回对。核心就三点:中间件必须拦截到 OPTIONS、响应头要合法、且不能和 credentials 冲突。
确认 Cors 中间件是否注册并前置
预检失败最常见原因是中间件根本没执行。打开 app/middleware.php,检查全局中间件数组里是否包含:
-
严格使用
think\middleware\Cors::class(不是CorsMiddleware,也不是字符串'cors') - 位置必须靠前,建议放在第 1 或第 2 位——它得在 Session、JWT、权限校验等中间件之前运行
- 多应用模式下,要配置对应应用目录下的 app/middleware.php,不是根目录那个
检查 OPTIONS 请求是否被正确响应
浏览器卡在预检阶段,控制台显示 404 或 500,说明请求压根没进中间件,或中间件没返回 200/204。重点验证:
- 用 curl 或 Postman 模拟 OPTIONS 请求:
curl -X OPTIONS -I http://your-api.com/api/user,看返回状态码和 header - 如果返回 404,可能是路由未定义 OPTIONS 方法,或 Nginx 把 OPTIONS 拦截了(见下一条)
- 如果返回 200 但缺
Access-Control-Allow-Origin等头,说明中间件执行了但逻辑有误(比如条件判断跳过了 header 设置)
处理带 credentials 的请求(如 Cookie、Authorization)
前端设置了 credentials: 'include',但浏览器报 “Credentials flag is true, but the 'Access-Control-Allow-Origin' value is not the literal '*'”,这是硬性限制,必须满足:
-
Access-Control-Allow-Origin不能是*,必须动态读取请求头中的Origin,并只对白名单域名返回对应值 -
Access-Control-Allow-Credentials必须设为true -
Access-Control-Allow-Headers不能用*,必须显式列出所有前端实际发送的字段(如Authorization、X-Auth-Token),大小写需一致
排查 Nginx 是否透传 Origin 头
Web 服务器可能直接拦截 OPTIONS 请求,导致 ThinkPHP 根本收不到。在 Nginx 的 server 块中加入:
- 显式拦截 OPTIONS 并返回 204:
if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin https://your-frontend.com; add_header Access-Control-Allow-Methods GET, POST, PUT, DELETE, OPTIONS; add_header Access-Control-Allow-Headers Content-Type, Authorization, X-Requested-With; add_header Access-Control-Allow-Credentials true; return 204; } - 确保
Origin头能透传到 PHP:检查是否有underscores_in_headers on;或fastcgi_pass_request_headers on;等配置缺失
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











