ThinkPHP 6 需手写 CorsMiddleware 并在路由前执行,否则无效;必须处理 OPTIONS 预检、禁用 method_filter 或放行 OPTIONS、Access-Control-Allow-Origin 不能为 *(启 credentials 时)、Nginx 需透传或直接添加 CORS 头。

CorsMiddleware 怎么写才生效直接给结论:ThinkPHP 6 默认不带跨域(https://www.php.cn/zt/20277.html)中间件,必须手写一个,并确保它在路由匹配前执行。很多人写了中间件但没生效,根本原因是注册位置不对或响应头被后续逻辑覆盖。
实操要点:
think\Middleware,handle() 方法里手动设置响应头app/middleware.php 中全局注册,或在 route/app.php 里用 ->middleware() 显式挂载到对应路由组AllowCrossDomain 类似命名的中间件,但后面又跑了 ValidateToken 或自定义异常处理,它们可能重置响应头
|
这是最常踩的坑:ThinkPHP 默认把 OPTIONS 当作非法方法拦截了,尤其在开启 method_filter 或使用了资源路由时。
解决路径很明确:
立即学习“PHP免费学习笔记(深入)(https://pan.quark.cn/s/7fc7563c4182)”;
handle() 开头加判断:if ($request->isOptions()) { return response('', 200)->header([...]); }app/config/app.php 中 'method_filter' => false,或至少把 OPTIONS 加进白名单数组Content-Type: application/json 就自动触发预检——只要带了 Authorization、X-Requested-With 或自定义 header,浏览器一定发 OPTIONScurl -X OPTIONS -I http://your-api.com/xxx 看真实响应头,别只信浏览器 Network 面板Access-Control-Allow-Credentials 设为 true 后跨域请求仍失败设了 true 却拿不到 cookie 或 token,大概率是前端没配 + 后端没配全。
(https://www.php.cn/xiazai/gongju/2229)
PHP 8.5.5(https://www.php.cn/xiazai/gongju/2229)
下载(https://www.php.cn/xiazai/gongju/2229)两端必须同步满足:
Access-Control-Allow-Credentials: true,Access-Control-Allow-Origin **不能是 ***,得写具体域名,比如 https://admin.example.comfetch 或 axios 请求必须显式加 credentials: 'include'(Vue Axios 示例:axios.get('/api/user', { withCredentials: true }))app/session.php 中 'domain' => '.example.com'(注意开头的点),且 cookie 的 SameSite 值设为 Lax 或 None(后者需同时配 Secure)本地测试好好的,一上 Nginx 就跨域失败,90% 是反代配置吞掉了响应头。
重点检查这几处:
proxy_hide_header 或 fastcgi_hide_header 误删了 Access-Control-* 头proxy_pass_request_headers off 这类非常规设置fastcgi_param 没过滤 header(虽然少见,但某些安全加固模板会加)add_header 'Access-Control-Allow-Origin' 'https://admin.example.com' always;,但要注意 always 参数,否则 4xx/5xx 响应不生效跨域不是“加几个 header 就完事”的事,它是客户端、应用层、反代层三者共同协商的结果。少一个环节对不上,就卡在预检或凭据传递上。尤其是 Origin 值的动态校验和 credentials 的严格配对,最容易被当成小问题忽略掉。