参考博客 :什么是跨域?跨域解决方法_越努力,越幸运!-CSDN 博客_跨域
一、为什么会出现跨域问题
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说 Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的 javascript 脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
二、什么是跨域
当一个请求 url 的协议、域名、端口三者之间任意一个与当前页面 url 不同即为跨域
跨域解决方案
创建一个中间件
php artisan make:middleware EnableCrossRequestMiddleware.php
在中间件内
public function handle(Request $request, Closure $next)
{
$response=$next($request);
$origin = $request->server('HTTP_ORIGIN') ? $request->server('HTTP_ORIGIN') : '';
$allow_origin = [
'http://localhost:8000',
];
if(in_array($origin,$allow_origin)){
$response->header('Access-Control-Allow-Origin', $origin);
$response->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Cookie, X-CSRF-TOKEN, Accept, Authorization, X-XSRF-TOKEN');
$response->header('Access-Control-Expose-Headers', 'Authorization, authenticated');
$response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS');
$response->header('Access-Control-Allow-Credentials', 'true');
}
return $next($request);
}
$allow_origin
数组变量就是你允许跨域的列表了,可自行修改。
在 Kernel.php 文件内注册
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'pro'=>EnableCrossRequestMiddleware::class
];
一定不要忘了路由使用中间件
Route::group(['middleware'=>'pro','prefix'=>'v2','namespace'=>'Api',],function (){
});
也可以内核文件注册该中间件
protected $middleware = [
App\Http\Middleware\EnableCrossRequestMiddleware::class,
];
在App\Http\Kernel
类的$middleware
属性添加,这里注册的中间件属于全局中间件
。
有时候返回的不是 laravel 的 response 对象而是 Symfony 的 response,所以会报 $response->header 方法找不到,所以添加 header 的方法要简单改一下,可以拼好一个数组直接调用一次,
$response->headers->add(['Access-Control-Allow-Origin' => $origin]);
$response->headers->add(['Access-Control-Allow-Headers' => 'Origin, Content-Type, Cookie,X-CSRF-TOKEN, Accept,Authorization']);
$response->headers->add(['Access-Control-Expose-Headers' => 'Authorization,authenticated']);
$response->headers->add(['Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, OPTIONS']);
$response->headers->add(['Access-Control-Allow-Credentials' => 'true']);
或者handle里直接写
public function handle($request, Closure $next)
{
header("Access-Control-Allow-Origin: *");
$headers = [
'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin'
];
$response = $next($request);
foreach($headers as $key => $value)
$response->header($key, $value);
return $response;
}