ThinkPHP6路由跨域默认不生效是因为CORS由中间件控制而非路由层自动处理;需手动启用think\middleware\Cors中间件并确保其执行顺序正确,且注意origin配置与credentials的兼容性。

ThinkPHP6 路由跨域请求为什么默认不生效
因为 ThinkPHP6 的 CORS(跨域资源共享)不是路由层自动处理的,而是靠中间件控制;Route::get() 或 Route::any() 这些定义本身完全不涉及跨域头。你配了路由却收不到 Access-Control-Allow-Origin,大概率是中间件没启用或顺序错了。
- 跨域响应头必须由中间件写入,不是路由或控制器自动加的
- 中间件必须在路由匹配之后、控制器执行之前运行,否则头可能被覆盖
- 如果用了多应用模式,中间件需注册到对应应用,不是全局 config 就万事大吉
怎么启用 thinkphp6 内置 CORS 中间件
ThinkPHP6 自带 think\middleware\Cors,但默认不启用。需要手动在应用中间件配置里打开,且注意它只对 HTTP 请求生效,命令行或 CLI 下无效。
- 编辑
app/middleware.php,把think\middleware\Cors::class加进去(推荐放在靠前位置,比如第 2 或 3 位) - 确保没有其他中间件(如自定义的 header 设置)重复设置
Access-Control-Allow-Origin,否则会冲突报错CORS header ‘Access-Control-Allow-Origin’ cannot be used with wildcard - 如果只需要对部分路由跨域,别用全局中间件,改用路由分组绑定:
Route::group(['middleware' => ['cors']], function () { ... })
跨域失败常见错误现象和对应检查点
浏览器控制台报 No 'Access-Control-Allow-Origin' header is present,不代表后端没配,很可能是中间件没跑、被跳过、或响应已被截断。
- 检查是否启用了
debug模式:关闭app_debug = false后,异常不会输出,中间件可能静默失败 - 确认请求方法:如果是
PUT/DELETE或带自定义 header(如Authorization),浏览器会先发OPTIONS预检;TP6 默认不自动响应预检,需确保Cors中间件支持并放行OPTIONS - 查看响应头:用
curl -I http://yourdomain.com/api/test看真实返回头,排除浏览器缓存干扰 - 注意 Nginx/Apache 反向代理:如果 TP6 前还有一层 Web 服务器,它可能过滤或覆盖了跨域头
自定义 Cors 中间件参数时要注意什么
think\middleware\Cors 支持传参,但参数名和行为容易误解。比如 'origin' => '*' 看似万能,但一旦要带 cookie 就必须指定具体域名,不能用通配符。
立即学习“PHP免费学习笔记(深入)”;
-
'origin' => ['https://a.com', 'https://b.com']:多域名白名单,注意协议、端口、斜杠都要一致 -
'withCredentials' => true:必须配合origin写死域名,且前端fetch要加credentials: 'include' -
'maxAge' => 3600:影响预检缓存时间,设太大可能导致修改配置后前端不刷新预检结果 - 不要在中间件里手动
header(),TP6 使用 PSR-7 响应对象,直接改$response->withHeader()
跨域真正卡住的地方,往往不是“怎么开”,而是“谁在写头、谁在删头、谁在拦截 OPTIONS”。盯住中间件执行顺序和响应对象生命周期,比反复调 header() 有用得多。


















