Laravel 5:仅在一个 URL 上路由 CORS 问题

Posted

技术标签:

【中文标题】Laravel 5:仅在一个 URL 上路由 CORS 问题【英文标题】:Laravel 5: routing CORS issue on just one URL 【发布时间】:2020-01-08 12:23:43 【问题描述】:

我正在尝试向外部 laravel 站点发出 2 个 ajax 请求。其中一个请求完美运行(“列表”)。另一个(“savedevice”)给我以下错误:

CORS 策略已阻止从源“null”访问“http://localhost/somesite/devicecreate”处的 XMLHttpRequest:请求的资源上不存在“Access-Control-Allow-Origin”标头。

origin 为 null,因为请求来自本地 html

我已经创建了一个适用于第一个路由但不适用于第二个路由的 CORS 中间件解决方案。

2个路由在web.php中存储如下:

  Route::post('/devicecreate','FrontEndController@savedevice')->middleware('cors');
  Route::post('/list', 'FrontEndController@list')->middleware('cors');

这是我在 javascript 中的 ajax 请求函数

var ajaxRequest = function ( url, data, callback ) 

        var  xhr = new XMLHttpRequest();

        xhr.onerror = function(e)  
              console.log("Ajax request error");
        ;

        xhr.addEventListener("load",function () 
              xhr.responseJSON = JSON.parse( xhr.responseText );
              callback( xhr.responseJSON);
        );

        xhr.open("POST", url );
        xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
        xhr.send(data);
;

目前(出于测试目的)两种路由方法都做同样的事情。但只有“/list”有效。

如果我尝试 php artisan route:list 我可以看到“devicecreate”和“list”都具有相同的方法、正确的操作和相同的中间件

我的 CORS 中间件如下所示:

<?php

  namespace App\Http\Middleware;

  use Closure;

  class Cors
  
     /**
      * Handle an incoming request.
      *
      * @param  \Illuminate\Http\Request  $request
      * @param  \Closure  $next
      * @return mixed
      */
     public function handle($request, Closure $next)
     

         if ($request->getMethod() == "OPTIONS") 
             return response(['OK'], 200)
             ->withHeaders([
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Methods' => 'GET,POST',
            'Access-Control-Allow-Headers' => 'Authorization,Content-Type,X-Requested-With,XMLHttpRequest',
          ]);
    

    return $next($request)
    ->header('Access-Control-Allow-Origin', '*')
    ->header('Access-Control-Allow-Methods', 'GET,POST')
    ->header('Access-Control-Allow-Headers','Authorization,Content-Type,X-Requested-With,XMLHttpRequest');

      
  

我也尝试运行 php artisan route:cache

我已尝试重命名路线,但没有任何区别。

谁能帮忙?

【问题讨论】:

【参考方案1】:

24 小时后,我为遇到以下任何情况的任何人提供了解决方案:

CORS / 跨域错误从外部来源发布 ajax(否则预检) 419 状态未知 从外部网站发布时围绕 CSRF 令牌的问题。

1) 创建一个 CORS 中间件 (https://laravel.com/docs/5.8/middleware)。您可以使用我上面显示的中间件代码。

2) 确保将中间件添加到受保护的 $routeMiddleware 下的 Http/Kernal.php 文件中,例如: 'cors' =&gt; \App\Http\Middleware\Cors::class,

3) 仅将中间件附加到需要它的路由上。就我而言,这是:

Route::post('/setdevice','FrontEndController@savedevice')->middleware('cors');
Route::post('/list', 'FrontEndController@list')->middleware('cors');

4) 记住要从 CSRF 令牌验证中排除您的外部 Ajax 请求! 我的问题是我忘记添加第二条路由了!所以就我而言,我将这些添加到 Http/Middleware/VerifyCsrfToken.php 中受保护的 $except 参数中:

 protected $except = [
        'list',
        'savedevice',
    ];

【讨论】:

以上是关于Laravel 5:仅在一个 URL 上路由 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

仅在 Laravel 中公开某些身份验证路由

laravel5.5路由使用name的好处

Laravel 5.4:发布没有表单或隐藏 url 的路由

在 Laravel 5.3 的中间件中访问路由 URL 参数

在 Ajax 调用中传递完整 URL 作为参数 - Laravel 5.1 路由

Laravel 5.0.* 中间件在处理路由之前从 url 中删除前缀语言环境