ThinkPHP跨域问题可通过四种方式解决:一、路由级allowCrossDomain()方法;二、自定义Cors中间件统一处理;三、控制器内手动设header;四、Nginx反向代理配置响应头。

如果您在使用ThinkPHP开发前后端分离项目时,前端请求被浏览器拦截并提示跨域错误,则很可能是服务端未正确配置跨域访问策略。以下是多种可行的配置方式:
一、路由级跨域设置(适用于特定API路由)
该方式通过在路由定义中链式调用allowCrossDomain()方法,仅对目标路由生效,不干扰其他接口,具备高可控性与低侵入性。它会自动注入标准CORS响应头,且优先级高于全局中间件。
1、打开route/app.php文件,在定义HTTP路由时添加->allowCrossDomain()调用。
2、若需允许多个指定前端域名,传入数组参数:->allowCrossDomain(['https://admin.example.com', 'http://localhost:3000'])。
立即学习“PHP免费学习笔记(深入)”;
3、若前端fetch需携带Cookie,必须显式启用凭据支持:->allowCrossDomain(['https://example.com'], true),此时Access-Control-Allow-Origin不可为*。
4、确保该调用位于Route::get()、Route::post()等路由定义之后,且未包裹在闭包内而遗漏执行。
二、自定义Cors中间件(推荐用于全局统一处理)
该方式通过创建独立中间件,在请求生命周期早期统一注入CORS头并主动响应OPTIONS预检请求,避免405错误及浏览器静默失败,是TP6最稳定可靠的全局方案。
1、执行命令生成中间件:php think make:middleware CorsMiddleware。
2、编辑app/middleware/CorsMiddleware.php,在handle()方法开头添加预检拦截逻辑:if ($request->isOptions()) { return response('', 204); }。
3、在拦截逻辑后设置响应头:$response->header('Access-Control-Allow-Origin', 'https://your-frontend.com'),注意不可同时设*与credentials: true。
4、必须显式声明允许的方法与请求头:$response->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')和$response->header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With')。
5、将\app\middleware\CorsMiddleware::class添加至app/middleware.php的中间件列表中,建议置于靠前位置以确保执行时机。
三、控制器内手动注入响应头(适用于TP5或临时调试)
该方式直接在控制器方法起始处调用header()函数或Response对象设置头信息,实现快速验证,但易受框架后续输出覆盖,不适用于生产环境的稳定部署。
1、在控制器方法第一行插入:header('Access-Control-Allow-Origin: *');
2、紧接着设置方法与头信息:header('Access-Control-Allow-Methods: GET, POST, OPTIONS');和header('Access-Control-Allow-Headers: Content-Type, Authorization');
3、如需支持凭证,增加:header('Access-Control-Allow-Credentials: true');,并同步将Origin值改为具体域名而非*。
4、对OPTIONS请求单独响应:if ($request->isOptions()) { return response('', 204); },防止预检失败。
四、Nginx反向代理配置(绕过PHP层跨域限制)
该方式在Web服务器层面统一添加响应头,完全脱离PHP代码控制,性能开销最低,适用于已部署线上环境且无法修改应用代码的场景。
1、进入Nginx站点配置文件,定位到对应server块内的location段。
2、添加以下指令:add_header 'Access-Control-Allow-Origin' 'https://your-frontend.com' always;
3、添加方法与头支持:add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;和add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;
4、显式处理预检请求: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' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; }



















