没有“Access-Control-Allow-Origin”标头 - Laravel

24

XMLHttpRequest无法加载http://myapi/api/rating。对预检请求的响应未能通过访问控制检查:所请求的资源没有'Access-Control-Allow-Origin'头。因此,源'http://localhost:8104'不允许访问。响应具有HTTP状态代码403。

我无法弄清楚为什么不能进行CORS请求。我已经安装了中间件,并将其添加到全局http内核中,但仍无法工作。尝试按照stackoverflow建议创建自定义中间件,但也不起作用。还尝试添加路由组。最后,我尝试在请求动作中手动设置响应标头。我真的卡住了-需要帮助!

请参见代码:https://gist.github.com/KerryRitter/0d7ababb7b9eb8d54f0ae55add9704a1


简单点,使用这个插件:https://github.com/barryvdh/laravel-cors - num8er
我做了,那就是我提到的中间件(忘了说了)。我按照我的Gist所示添加到内核中。 - Kerry Ritter
要不要像这样保留它:'middleware' => [\Barryvdh\Cors\HandleCors::class] - num8er
好的,我移除了'cors'的注册和Cors类。移除了路由组。移除了请求操作头。我在Kernel中只有以下内容: protected $middleware = [ ... \Barryvdh\Cors\HandleCors::class ];仍然没有运气 :( - Kerry Ritter
解决了我的问题:我没有将"Barryvdh\Cors\ServiceProvider::class"添加到config/app.php提供程序数组中。 - Kerry Ritter
10个回答

36
如果您正在使用 Laravel 5.5Laravel 5.x,并且遇到了与 No 'Access-Control-Allow-Origin' header is present on the requested resource 相同的问题,请使用以下软件包并配置您的系统。
步骤1:
composer require barryvdh/laravel-cors

步骤2

您还需要将Cors\ServiceProvider添加到您的config/app.php提供程序数组中:

FruitCake\Cors\CorsServiceProvider::class,

为了允许所有路由使用 CORS,在 app/Http/Kernel.php 类的 $middleware 属性中添加 HandleCors 中间件:

全局使用:

protected $middleware = [
    // ...
    \Fruitcake\Cors\HandleCors::class,
];

用于中间件的情况:

protected $middlewareGroups = [
   'web' => [
       // ...
   ],

   'api' => [
        // ...
        \Fruitcake\Cors\HandleCors::class,
    ],
];

步骤 3

完成安装后,请运行下面的命令以发布供应商文件。

php artisan vendor:publish --provider="Fruitcake\Cors\ServiceProvider"

希望这个答案能帮助到像我一样面临相同问题的人。


5
在config/app.php文件中,我们需要添加Fruitcake\Cors\CorsServiceProvider::class。 - Elby
参考:https://github.com/fruitcake/laravel-cors - Gato de Schrödinger

24

Laravel默认限制跨域请求,以防止安全问题。我们需要创建一个Cors中间件来接受来自不同源的请求。

步骤1:创建Cors中间件。

php artisan make:middleware Cors

步骤2:在返回之前,在处理函数中添加以下行。

//header('Access-Control-Allow-Origin:  *');
header('Access-Control-Allow-Origin:  http://localhost:4200');
header('Access-Control-Allow-Headers:  Content-Type, X-Auth-Token, Authorization, Origin');
header('Access-Control-Allow-Methods:  POST, PUT');

步骤3:在app/Http/Kernel.php文件中注册中间件。

Add below line in $middleware array 

\App\Http\Middleware\Cors::class,

步骤4:现在我们需要在app / Http / Kernel.php文件中调用中间件

Add below line in $routeMiddleware array 

'cors' => \App\Http\Middleware\Cors::class,

2
谢谢,这是唯一对我有效的方法。我相信其他答案(或我在网上看到的东西)没有提到我们需要将中间件添加到$middleware数组中的事实。 - MrCujo
非常感谢!没有使用任何软件包就完成了这项工作。 - Varun Pradhan
1
使用 * 代替主机来源更有效。数组中也缺少了 Cors.php 中间件。谢谢。 - Jose Mhlanga
1
这是唯一可行的方法。网络上有很多错误的资源。 - ldmuniz
以任何方式都不利于生产网站吗?我的意思是它是否以任何方式影响安全性? - Mostafa Said

5

解决了我的问题:我没有将"Barryvdh\Cors\ServiceProvider::class"添加到config/app.php提供程序数组中。 - Kerry Ritter

3
最近在laravel 5.4中,我向自己的网站发送ajax post请求时遇到了这个错误。出现此错误的原因有两个:
错误信息:XMLHttpRequest无法加载https://[mydomain].com/quote/short。对预检请求的响应未能通过访问控制检查:所请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,源'http://[mydomain].com'不允许访问。
以上错误的原因是我从https域向http域发送请求,当我将其更改为https后,错误得以解决。然后,由于类似的原因,我再次遇到了同样的错误,这次是由于一个域名带有www.而另一个没有,当我将www.添加到两个域名中后,问题迎刃而解。
对于跨域请求,我使用以下解决方案:
  1. Create a middleware (cors in my case) having code below

    return $next($request)
        ->header('Access-Control-Allow-Origin', '*')
        ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    
  2. Insert middle-ware into routeMiddleware array in kernal.php

    'cors' => \App\Http\Middleware\Cors::class,

  3. Add middleware to the respected route

    Route::get('myRoute', ['middleware' => 'cors' , 'uses'=> 'MyController@Action']

希望我的答案能够帮助到遇到和我一样问题的人。

3
简单的答案是将Access-Control-Allow-Origin头设置为localhost或*。以下是我通常的做法: 创建一个名为Cors的简单中间件:
php artisan make:middleware Cors

将以下代码添加到app/Http/Middleware/Cors.php中:
public function handle($request, Closure $next)
{
    return $next($request)
        ->header('Access-Control-Allow-Origin', '*')
        ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
}

您可以将 * 替换为 localhost 或保留原样。

接下来是加载中间件的步骤。请将以下行添加到 app/Http/Kernel.php 中的 $routeMiddleware 数组中。

'cors' => \App\Http\Middleware\Cors::class, 

最终步骤是在你想要设置访问来源头信息的路由上使用中间件。假设您正在谈论 Laravel 5.3 中的新 API 路由,那么在 app/Providers/RouteServiceProvider.php 文件中 mapApiRoutes() 函数内执行(您可以删除或注释该函数先前的代码):

Route::group([
        'middleware' => ['api', 'cors'],
        'namespace' => $this->namespace,
        'prefix' => 'api',
    ], function ($router) {
         //Add you routes here, for example:
         Route::apiResource('/posts','PostController');
    });

2

好的,这是我的尝试。 如果我使用错误的令牌访问受保护的API,Passport会返回401和{"message":"Unauthenticated."}。

但是由于响应中不存在CORS标头,我的Vue应用程序会收到CORS错误,并且无法处理响应代码。

所以在Laravel 5.8的http/kernel.php $middlewarePriority中添加\Barryvdh\Cors\HandleCors::class在\App\Http\Middleware\Authenticate::class之前。

以下是我的代码:

Original Answer翻译成"最初的回答"

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        'throttle:300,1',
        'Localization',
        'bindings',
        'cors'
    ],
];

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,

    // Add Localization MiddleWare
    'Localization' => \App\Http\Middleware\localization::class,
    'cors' => \Barryvdh\Cors\HandleCors::class,
];

protected $middlewarePriority = [
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,

    //add to handle cors before authenticate
    \Barryvdh\Cors\HandleCors::class,

    \App\Http\Middleware\Authenticate::class,
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
];

"最初的回答" -> "原始答案" 希望这能帮助其他人。

1
在我的情况下,我运行了更新以将 Laravel 从 v7.x 移动到 v9.x,结果出现了本地 API 访问 CORS 错误。
如果以上方法都不起作用,我追踪到了 TrustProxies 中间件中的 $headers 变量是问题所在。
这个变量的原始值是 Request::HEADER_X_FORWARDED_ALL;
在将其更新为以下内容后,它恢复正常了。
Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB;
参考 https://laravel.com/docs/9.x/upgrade 和 Trusted Proxies 部分。
对于我来说,这意味着阅读整个升级文档,即使你认为其中的元素并不适用于你的项目...

0

只是想补充一些内容,这是我在采取已接受答案中提到的步骤之外必须要做的事情。

在几次生产部署(Laravel版本^7.0在Nginx上)后,即使按照此处所述设置了HandleCors,我仍然遇到了CORS错误。 在运行php artisan config:cachecomposer installcomposer dump-autoload之后,它开始工作。

希望这能帮助那些在部署过程中没有更新任何配置文件时尝试调试出错的人。


0

我在一个组合项目中使用Reactjs前端和Laravel后端时,遇到了"预检请求未通过访问控制检查:没有'Access-Control-Allow-Origin"的问题。 我通过清除Heroku上部署的Reactjs应用程序的缓存来解决了这个问题。

如何清除构建缓存?


0
我之前出错是因为我的模型中缺少了一些特征。
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;

所以我在特定的路由中添加了头部,修复了这些错误,然后我的头部恢复正常。
header('Access-Control-Allow-Origin: *');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接