Laravel 解决 ajax 跨域问题

2021-08-21T16:44:00

网站需要临时获取后台数据,因与接口地址不一样,所以请求存在跨域的问题。

在使用 tp 或 ci 框架时,处理跨域比较直接:header("Access-Control-Allow-Origin: *");。可以放在在请求的控制器构造函数里,表示控制器下的方法都支持跨域,也可以放在单个方法表示单个方法支持跨域。

Laravel 与这些框架差不多,唯一需要注意的是,如果方法请求参数使用依赖注入的 Request 对象,则跨域头部需要在实例对象生命周期更前面一点去添加跨域头,比如类的构造函数或者路由。考虑到项目中可能还会有类似的跨域请求,所以考虑使用中间件来允许跨域请求。

首先在默认中间件路径 app/Http/Middleware 下添加允许跨域的中间件

AccessControlAllowOrigin.php

<?php

namespace App\Http\Middleware;

use Closure;

class AccessControlAllowOrigin
{
    public function handle($request, Closure $next)
    {
      $response = $next($request);
      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;
    }
}

然后在内核文件注册该中间件

可以选择全局应用,或者针对路由应用。

全局应用:

    protected $middleware = [
        // more
        App\Http\Middleware\AccessControlAllowOrigin::class,
    ];

路由应用:

    protected $routeMiddleware = [
        'cors' => App\Http\Middleware\AccessControlAllowOrigin::class,
    ];

考虑到实用性,选择路由中间件进行注册。

最后是应用路由中间件

有两种方式,一种是在路由定义上增加 ->middleware('cors')cors 为前面定义的中间件别称。

另一种是在控制器的构造函数中添加 $this->middleware('cors')

需要注意的事项

ajax 请求实际是两个请求,一个为 OPTIONS 类型,一个为请求类型。所以,如果在应用了跨域中间件后,访问仍然报错,记得查询一下 OPTIONS 路由是否有定义。

以 POST 请求类型为例,增加 OPTIONS 请求类型:

Route::match(['options', 'post'], '/', function () {
    //
});

另外据 Laravel 文档里介绍,Laravel 可以使用配置的值自动响应 CORS OPTIONS 请求。

跨域资源共享 (CORS)

Laravel 可以使用您配置的值自动响应 CORS OPTIONS 请求。所有的 CORS 设置都可以在您的
cors 配置文件中设置, 默认情况下的全局中间件堆中的 HandleCors 中间件会自动处理 OPTIONS 请求。

参考:
laravel 解决ajax 跨域
Laravel 跨域解决方案
路由 |《Laravel 8 中文文档 8.x》| Laravel China 社区

当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »