ThinkPHP 6.0 默认不支持跨域,推荐使用自定义CorsMiddleware中间件统一处理:拦截OPTIONS预检请求并返回204,为正常请求设置Access-Control-Allow-Origin等响应头,需注意credentials与*不可共存、避免服务器重复添加CORS头。

ThinkPHP 6.0 默认不开启跨域支持,必须手动配置。最稳妥、推荐的方式是自定义 CORS 中间件,它能统一处理所有 HTTP 请求,并正确响应 OPTIONS 预检请求,避免 405 或静默失败。
用中间件统一处理(推荐)
这是 TP6 最稳定可靠的方案,覆盖全站接口,逻辑清晰且易于维护。
- 执行命令生成中间件:
php think make:middleware CorsMiddleware - 编辑
app/middleware/CorsMiddleware.php,在handle()方法中写入:- 先判断是否为 OPTIONS 请求:若成立,直接返回空响应并设状态码 204
- 再为正常请求设置响应头,例如:
$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') - 如需携带 Cookie 或 token,加:
$response->header('Access-Control-Allow-Credentials', 'true'),此时Origin必须指定具体域名,不能为*
- 在
app/middleware.php的全局中间件数组中,把\app\middleware\CorsMiddleware::class加进去,建议放在首位
按路由单独启用(轻量灵活)
适合只对部分 API 开放跨域,比如仅 /api/ 下的接口,不影响其他路由。
- 在
route/app.php中定义路由时链式调用->allowCrossDomain() - 不传参即允许任意源:
Route::get('user', 'User/get')->allowCrossDomain(); - 限制来源时传数组:
->allowCrossDomain(['https://admin.example.com', 'http://localhost:3000']) - 带 Cookie 时必须显式启用凭据:
->allowCrossDomain(['https://example.com'], true),且 Origin 不可为*
注意几个关键细节
这些地方容易出错,导致跨域仍失败:
-
预检请求必须被拦截:浏览器发 OPTIONS 时,中间件或路由没处理就会报 405;务必在中间件里用
$request->isOptions()判断并提前返回 -
* 和 credentials 不能共存:一旦设了
Access-Control-Allow-Credentials: true,Access-Control-Allow-Origin就只能是具体域名,比如https://a.com,不可填* -
Nginx/Apache 不要重复加头:如果 PHP 层已配 CORS,服务器层就别再用
add_header设置相同字段,否则可能触发「multiple values」错误 -
前端也要配合:fetch 要加
credentials: 'include',jQuery 要设xhrFields: { withCredentials: true },否则后端即使开了 credentials 也拿不到 Cookie 或 Authorization
其他方式(慎用)
控制器内用 response()->header() 可行,但每个接口都要写,不便于统一管理;直接 header() 在 TP6 中易因输出已开始而失效。Nginx 配置虽快,但无法动态判断 Origin,也不利于多环境切换。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











