ThinkPHP 6 的 CORS 中间件默认不生效,因其未启用、不处理 OPTIONS 预检请求,且需在 app/middleware.php 中显式注册并确保路由分组挂载正确;同时需避免与 Nginx/Apache 的 CORS 设置冲突,并严格配置 origin 和 credentials。

ThinkPHP 6 的 cors 中间件为什么没生效?
因为默认不启用,且只对 HTTP 请求生效,不处理预检(OPTIONS)请求的自动响应。很多开发者配了中间件却收不到响应头,其实是没在路由里显式注册或漏掉了中间件顺序。
-
app/middleware.php中必须把Cors::class加入全局或分组中间件列表,不能只靠配置文件 - 如果用了路由分组(比如
api),得确保中间件挂载到了该分组下,否则静态资源或非 API 路由不会走 CORS 流程 - ThinkPHP 6.0+ 的
Cors中间件默认不处理OPTIONS预检请求 —— 它只给正常请求加响应头;真正拦截并返回 204 的是底层的think\middleware\Cors,但需配合allow_cross_domain配置项开启 - 检查
config/cors.php是否存在,且origin值不是*+credentials为true(这会直接被浏览器拒绝)
Apache 和 Nginx 下直接加 Header 与 ThinkPHP 的 CORS 冲突吗?
会,而且优先级容易搞反。服务器层加的 Access-Control-Allow-Origin 如果和 PHP 层重复设置,可能被覆盖或触发浏览器报错「The 'Access-Control-Allow-Origin' header contains multiple values」。
- Apache:用
Header set比Header add更安全,避免重复;若启用了 ThinkPHP 的 CORS 中间件,建议关掉 Apache 的同类设置 - Nginx:
add_header默认不继承父级作用域,子 location 里要显式重写;更稳妥的是只在 Nginx 层统一处理预检请求(if ($request_method = 'OPTIONS') { return 204; }),让 PHP 只管业务响应头 - 验证方式:用
curl -I http://your-api.com/xxx看响应头是否唯一、无重复字段
跨域带 Cookie 时 credentials 设为 true 却报错?
这是最常踩的坑:前端 fetch({ credentials: 'include' }) 和后端 credentials => true 必须同时满足,且 origin 不能为 * —— 必须写死具体域名或做白名单判断。
-
config/cors.php中'origin' => ['https://a.com', 'https://b.net'],不能留空或写['*'] - 前端请求头必须带
Origin,且值要和后端白名单完全匹配(协议、端口、域名缺一不可) - ThinkPHP 的
Cors中间件不会自动读取$_SERVER['HTTP_ORIGIN']做动态匹配,如需灵活支持多个子域,得手动在中间件里重写$this->origin属性 - Cookie 还需确保后端响应头有
Access-Control-Allow-Credentials: true,且前端Set-Cookie的Domain和Path设置正确(比如不能跨二级域设Domain=.com)
生产环境 Nginx + ThinkPHP 部署时 CORS 失效的隐蔽原因
不是代码问题,而是 Nginx 把 OPTIONS 请求转给了 PHP-FPM,而 ThinkPHP 默认路由不处理纯 OPTIONS,导致 404 或 500,浏览器就判定预检失败。
立即学习“PHP免费学习笔记(深入)”;
- 在 Nginx 的
location ~ \.php$块外,加一段专门捕获 OPTIONS 的规则: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"; add_header Access-Control-Allow-Credentials "true"; return 204; } - 别依赖 PHP 层处理 OPTIONS —— 它慢、不可靠,还可能被路由规则跳过
- CDN 或 WAF(如阿里云、Cloudflare)可能缓存了预检响应,导致新配置不生效;临时关掉 CDN 缓存或加 Cache-Control: no-store 排查
curl -X OPTIONS -I 看预检响应,再看业务请求的响应头是否完整;只要预检卡住,后面全白搭。很多人调半天接口,其实根本没走到 PHP。


















