laravel8 解决跨域问题

Laravel框架
492
0
0
2022-09-11
标签   跨域请求

参考博客 :什么是跨域?跨域解决方法_越努力,越幸运!-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;
}

laravel8 解决跨域问题