Mac环境下使用Herd运行Laravel项目遭遇CORS跨域问题求助
兄弟我太懂你这种换个开发环境就踩坑的郁闷了!先帮你把问题拆明白,再给你几个接地气的解决办法。
先搞懂:为啥现在会出CORS错误?
你现在的问题核心是浏览器的同源策略在搞事情:你前端页面跑在localhost:8000,但AJAX请求发去了localhost(默认是80端口)——浏览器会把“不同端口”当成完全不同的源,所以会触发CORS跨域检查,而你的后端没返回允许跨域的响应头,直接就被浏览器拦截了。
那Windows上为啥没这问题?
大概率是你Windows的开发环境是前后端同域的,几种常见情况:
- 之前你在Windows上是用
php artisan serve启动项目,前后端都跑在8000端口,同域自然不会触发CORS - 或者用了Valet、WAMP这类工具,给项目配了自定义域名(比如
myproject.test),前后端都用这个域名访问,同域无压力 - 要是项目是前后端不分离的(比如Laravel Blade渲染页面),点击链接是页面跳转不是AJAX异步请求,那浏览器根本不会触发CORS检查(CORS只管AJAX、Fetch这类异步请求)
- 其他开发者的环境也是同域部署的,所以没碰到这个问题
接下来给你几个解决办法,按省心程度排序:
方法一:让前后端同域(最推荐,本地开发零配置)
Herd默认会给每个Laravel项目分配一个.test后缀的本地域名——比如你的项目文件夹叫myapp,那直接访问myapp.test就能打开后端服务。你只需要把前端的请求地址改成这个域名(比如把所有http://localhost换成http://myapp.test),前后端就成了同域,浏览器直接放行,再也不会报CORS错了。
方法二:临时给本地环境加CORS响应头(不用装包)
如果不想改域名/端口,咱可以自己写个简单的中间件搞定:
- 在
app/Http/Middleware目录下新建一个Cors.php文件,内容如下:
<?php namespace App\Http\Middleware; use Closure; class Cors { public function handle($request, Closure $next) { return $next($request) ->header('Access-Control-Allow-Origin', 'http://localhost:8000') ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS') ->header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); } }
- 打开
app/Http/Kernel.php,找到$middleware数组,把刚才的中间件加进去:
protected $middleware = [ // 其他中间件... \App\Http\Middleware\Cors::class, ];
这样所有后端响应都会带上允许localhost:8000跨域的头,本地开发就能正常请求了。注意:这个方法只适合本地开发用,线上环境千万别这么写死,要严格控制允许的源!
方法三:用fruitcake/laravel-cors包(适合需要灵活配置的场景)
虽然你疑惑为啥别人不用,但如果你的项目是前后端分离的,需要在不同环境(本地、测试、生产)配置不同的跨域规则,装这个包是最规范的做法。安装后修改config/cors.php文件,把localhost:8000加入允许的源列表,就能搞定跨域问题。其实很多人没说装这个包,可能是他们的环境本来就同域,根本没触发CORS而已。
总结一下
你现在的问题本质就是前后端端口不同导致跨域,Windows上是同域所以没触发。优先用方法一(同域访问),省心又符合本地开发的最佳实践,不用瞎折腾配置。
备注:内容来源于stack exchange,提问作者Cornel Verster

