相同代码部署不同子域名时Laravel+axios出现CORS跨域问题
问题原因排查及解决方案
核心诱因
OPTIONS预检请求能正常返回CORS头、POST请求无CORS头,本质是POST请求在到达Fruitcake\Cors\HandleCors中间件的响应处理逻辑前,就被其他逻辑提前返回了响应,CORS头没有被追加到最终响应中。结合场景特征,常见问题点按排查优先级排序如下:
1. 认证/权限中间件提前拦截请求
第二套部署的axios不会携带Authorization头,若请求的接口需要身份认证,请求会直接被Laravel的认证中间件(如auth:sanctum/auth:api)拦截返回401状态码,该响应未经过CORS中间件的后置处理,因此没有CORS头。
第一套部署哪怕未登录也会携带空值
Authorization头,若后端的认证逻辑对空值头有兼容处理(比如直接判定为未登录但仍走到业务逻辑返回响应),就不会触发提前拦截。
2. 全局中间件注册顺序错误
Fruitcake\Cors\HandleCors中间件必须注册在app/Http/Kernel.php的$middleware全局中间件数组的第一位,优先级高于所有路由、认证、表单验证、CSRF校验类中间件。如果注册位置靠后,任何提前返回的响应(如表单验证错误422、CSRF校验失败419)都会跳过CORS头的追加。
两套部署代码一致的情况下,需确认第二套部署是否修改过
Kernel.php配置,或者部署过程中缓存的配置没有更新,可执行php artisan config:clear清除配置缓存后验证。
3. CORS配置路径匹配异常
检查config/cors.php中的paths配置,只有匹配该规则的请求才会追加CORS头。如果POST请求的路径存在重定向(比如Laravel默认会将末尾带/的请求301重定向到不带/的路径),重定向后的路径未匹配paths规则,就不会返回CORS头。
4. Web服务器配置拦截头输出
若第二套部署的Nginx/Apache在服务层面配置了CORS头,需注意Nginx的add_header指令默认仅对200/201/301/302等少数状态码生效,若POST请求返回4xx/5xx错误码,服务端配置的CORS头不会被追加,而OPTIONS请求返回204状态码符合生效条件因此正常返回头。
排查步骤
- 用Postman/Curl直接模拟POST请求到后端接口,确认请求的实际响应状态码和响应内容,优先修复接口本身的业务错误(如认证失败、参数错误)
- 确认
HandleCors中间件的注册位置为全局中间件首位,执行php artisan config:clear清除配置缓存 - 若使用web服务器配置CORS头,要么删除服务端配置完全由Laravel CORS中间件处理,要么给
add_header指令增加always参数,示例:add_header Access-Control-Allow-Origin "https://app.subdomain2.domain.com" always; - 校验第二套前端axios配置,保持和第一套一致的
withCredentials、默认header配置,确保Authorization头哪怕为空也会携带
内容的提问来源于stack exchange,提问作者ied3vil
相关产品推荐
相关产品推荐

