TP6跨域报错主因是后端响应头缺失或错误;需先确认协议、域名、端口三者是否完全一致,再按路由级allowCrossDomain()或自定义Cors中间件精准配置,禁用Nginx/Apache重复头。

TP6 接口跨域报错,核心是响应头没发对、没发全、或根本没发出来。不是前端写错了,而是后端在关键环节漏了动作。
确认是否真跨域
先看协议、域名、端口三者是否完全一致。比如:
- 不跨域:http://localhost:3000 → http://localhost:3000/api
- 跨域:http://localhost:3000 → https://api.example.com(协议不同)
- 跨域:http://localhost:3000 → http://localhost:8080(端口不同)
只有确认是跨域,才需配置 CORS;否则加头反而可能引发干扰。
用路由级 allowCrossDomain() 快速启用
适合只开放 /api/ 类接口的前后端分离项目,简单安全:
- 在 route/app.php 中写:Route::get('api/user', 'Api/User@index')->allowCrossDomain();
- 若需带 Cookie 或 Authorization,必须传两个参数:
Route::post('api/login', 'Api/Login@login')->allowCrossDomain(['https://admin.example.com', 'http://localhost:3000'], true); - 注意:第一个参数不能含 *,第二个参数为 true 时,必须是明确域名数组
- 仅 HTTP/HTTPS 路由生效,console、event 等类型路由不触发
手写中间件精准控制(推荐生产环境)
新建 app/middleware/Cors.php,内容如下:
- 开头拦截 OPTIONS 请求并返回 204:
if ($request->isOptions()) { return response('', 204); } - 读取请求头 origin:
$origin = $request->header('origin'); - 白名单校验(从 config('cors.allow_origins') 读取完整 URL):
if (in_array($origin, $whitelist)) {
$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',
'Access-Control-Allow-Headers' => 'Authorization,Content-Type,X-Requested-With,X-Token'
]); - 确保该中间件注册在 app/middleware.php 数组首位,避免被 session 或 auth 拦截绕过
避坑要点
- 别在中间件里直接写 header() 函数——TP6 响应走 PSR-7 对象,手动调用会被覆盖
- 带 credentials: 'include' 时,Access-Control-Allow-Origin 绝不能设为 *,必须动态匹配 origin
- Nginx/Apache 层如果也加了 CORS 头,务必关掉,否则出现 “multiple values” 报错
- Access-Control-Allow-Headers 必须精确列出前端实际发送的字段,比如发了 X-Token,就必须包含它,不能写 *











