在 Laravel 研发项目中,一个典型问题就是前后端 跨域资源共享(CORS)问题。
以往解决方法很多,包含 JSONP 等,但我并不赞成用太多的“奇技淫巧”,在 Laravel 7 版本中已经有官方解决方案,我们还是应该尊重 Laravel 团队的智慧,用官方解决方案。
这个解决方式就是用 Middleware ,在必要的 API 响应中增加Access-Control-Allow-Origin
信息头,这样客户端就可以正常访问一个跨域资源。
先写一个简单的 前端访问 页面
<!DOCTYPE html><html><head><title>CORS Ajax Test</title><script src="/ajax/libs/jquery/3.4.1/jquery.min.js" crossorigin="anonymous"></script></head><body><script type="text/javascript">$.ajax({type: "GET",dataType: "json",url: 'http://localhost:8000/api/hello-cors',success: function(data){console.log(data);}});</script></body></html>
这里是访问一个本地 8000 端口上的资源(Laravel 本地研发一般就用 8000 端口),而我们可以将这个页面运行在另外的端口上(默认 80 端口),这样就形成了跨域资源访问。
在 Laravel 7 中已经默认安装fruitcake/laravel-cors
包,这个包就是用来处理 CORS 消息的,在 config 目录里面的 cors.php 就存储了其配置参数,用默认参数就可以。
然后在 Laravel 的routes/api.php
中建立一个简单的处理函数
Route::get('/hello-cors', function(Request $request){return response()->json(['Hello Laravel with CORS']);});
这样刷新原有的 HTML 文件,就可看到返回的Hello Laravel with CORS
消息。
其实在原有的 Laravel5 或者 Laravel 6 项目中,可按照如下方法编写一个简单的中间件,其原理也相同,实现效果也是类似的。
用 PHP artisan 命令建立一个 中间件
php artisan make:middleware Cors
然后将这个中间件的 handle 函数更改为
public function handle($request, Closure $next){return $next($request)->header('Access-Control-Allow-Origin', '*')->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')->header('Access-Control-Allow-Headers', 'Content-Type, Authorizations');}
再到app/Http/
目录中修改Kernel.php
文件的$middleware
数组,增加一行以注册这个中间件
protected $middleware = [...AppHttpMiddlewareCors::class,];
这样所有 HTTP 返回的消息中都自动增加必要的 CORS 头。
题图来源:Photo by Markus SpiskeonUnsplash