ThinkPHP6.0配置跨域需正确设置CORS响应头并处理OPTIONS预检请求,推荐路由级配置(allowCrossDomain)、自定义Cors中间件、think-cors扩展或Nginx层兜底四种方式,须注意credentials与通配符*互斥。

ThinkPHP6.0 配置跨域,核心是正确设置 CORS 响应头,并妥善处理 OPTIONS 预检请求。不能只靠 header() 硬写,也不能忽略凭据(credentials)与通配符 * 的互斥关系。推荐按实际场景选择以下方式之一,避免混用导致响应头重复或被覆盖。
路由级配置:精准控制单个或一组接口
适用于仅部分 API 需要跨域,比如后台管理接口对前端独立域名开放。它优先级高、侵入性低,且自动处理 OPTIONS 预检。
- 在
route/app.php中定义路由时链式调用:->allowCrossDomain() - 允许所有来源:
Route::get('api/user', 'User/index')->allowCrossDomain(); - 指定白名单(支持数组):
->allowCrossDomain(['https://admin.example.com', 'http://localhost:8080']) - 启用 Cookie 或认证凭据时,必须传第二个参数
true,且 origin 不能为*:->allowCrossDomain(['https://admin.example.com'], true) - 注意:该方法仅对 HTTP/HTTPS 路由生效,不作用于 console、event 或命令行请求
自定义 Cors 中间件:全局统一管控
适合前后端完全分离的项目(如 Vue/React 对接 TP6 API),需手动拦截 OPTIONS 并设置完整响应头,否则易出现 405 错误或静默失败。
- 执行命令生成中间件:
php think make:middleware CorsMiddleware - 编辑
app/middleware/CorsMiddleware.php,handle方法内先判断预检:if ($request->isOptions()) { return response('', 204); } - 再对响应对象设置头信息(注意顺序,必须在
$next($request)之后、return之前):$response->header('Access-Control-Allow-Origin', 'https://your-frontend.com');$response->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');$response->header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');$response->header('Access-Control-Allow-Credentials', 'true'); - 在
app/middleware.php全局中间件数组中,把该中间件放在首位,确保最早执行、最晚结束
使用 think-cors 扩展:标准化白名单与动态匹配
官方维护的扩展,支持路径匹配、正则 origin、缓存时间等高级配置,适合多前端、多子域或需要精细权限控制的项目。
立即学习“PHP免费学习笔记(深入)”;
- 安装:
composer require topthink/think-cors - 发布配置:
php think vendor:publish topthink/think-cors(或手动创建config/cors.php) - 关键配置示例:
'paths' => ['api/*'],'allowed_origins' => ['https://a.com', 'https://b.net'],'allowed_origins_patterns' => ['#^https?://.*\.example\.com$#'],'supports_credentials' => true,'max_age' => 7200 - 注册中间件:
\think\middleware\Cors::class加入app/middleware.php
服务器层兜底(Nginx):绕过 PHP 层干扰
当 PHP 层配置不稳定、或需兼容旧版 TP、或中间件失效时,可直接在 Nginx 添加响应头,尤其适合生产环境统一收敛策略。
- 在对应
location块中添加:add_header 'Access-Control-Allow-Origin' 'https://your-frontend.com' always;add_header 'Access-Control-Allow-Credentials' 'true' always;add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always; - 显式处理 OPTIONS 请求:
if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' 'https://your-frontend.com'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With'; return 204; } - 注意:Nginx 的
add_header默认不继承父级,子location需重写;若同时启用了 PHP 层 CORS,建议关闭 Nginx 的同类设置,避免头字段重复



















