ThinkPHP6.0跨域需通过中间件显式处理OPTIONS预检并动态设置响应头;推荐启用内置Cors中间件、路由级allowCrossDomain()或自定义CorsMiddleware,且Nginx需透传Origin头。

前端请求被浏览器拦截并提示跨域错误,是因为ThinkPHP6.0默认不响应OPTIONS预检、未设置Access-Control-Allow-Origin头、或credentials与通配符origin冲突;必须通过中间件显式处理预检请求并动态写入响应头,而非仅修改配置文件。
启用内置Cors中间件(最简方式)
第一步:打开app/middleware.php文件,找到全局中间件数组。
第二步:在数组靠前位置(建议第2或第3位)插入\think\middleware\Cors::class,确保它位于Session、JWT等业务中间件之前——否则预检请求可能被提前终止而无法响应。
第三步:保存后测试。若前端只发简单GET/POST且无自定义Header,此时应能收到Access-Control-Allow-Origin头。
立即学习“PHP免费学习笔记(深入)”;
【必须严格使用类名\think\middleware\Cors::class,写成'cors'或CorsMiddleware::class将完全不生效】
路由级跨域(精准控制单组API)
适用于只需对/api/*等特定路径开放跨域,不影响其他路由。
方法一:在route/app.php中定义路由时链式调用->allowCrossDomain():
例如:Route::post('api/login', 'Api/LoginController@login')->allowCrossDomain(['https://admin.example.com', 'http://localhost:3000']);
方法二:对整个路由分组启用:
Route::group('api', function () { Route::get('user', 'Api/UserController@index'); })->middleware(\think\middleware\Cors::class);
【allowCrossDomain()优先级高于全局中间件,但仅作用于当前路由,闭包内未执行该方法则无效】
自定义Cors中间件(生产环境推荐)
这是唯一能同时解决OPTIONS卡死、credentials冲突、Origin白名单校验的可靠方案。
① 执行命令生成中间件:php think make:middleware CorsMiddleware
② 编辑app/middleware/CorsMiddleware.php,替换handle方法为:
public function handle($request, \Closure $next)
{
if ($request->isOptions()) {
return response('', 204);
}
$response = $next($request);
$origin = $request->header('origin');
$allowedOrigins = ['https://admin.example.com', 'https://app.example.com'];
if (in_array($origin, $allowedOrigins)) {
$response->header('Access-Control-Allow-Origin', $origin);
$response->header('Access-Control-Allow-Credentials', 'true');
}
$response->header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
$response->header('Access-Control-Allow-Headers', 'Content-Type,Authorization,X-Requested-With,X-Auth-Token');
return $response;
}
③ 将\app\middleware\CorsMiddleware::class添加到app/middleware.php中间件列表顶部。
这一步操作起来很简单,直接把文件拖进去就行。
【若前端启用了withCredentials: true,Access-Control-Allow-Origin绝不能设为*,必须动态匹配且白名单含完整协议+域名+端口】
验证Nginx是否透传Origin头
登录服务器,编辑Nginx站点配置文件,在server块内添加:
proxy_set_header Origin $http_origin;
然后重启Nginx:sudo nginx -s reload。
若Nginx层已自行添加CORS头,必须全部删除,否则会触发重复头报错。



















