在某些系统上的 Laravel 中出现 Cors 错误

Posted

技术标签:

【中文标题】在某些系统上的 Laravel 中出现 Cors 错误【英文标题】:Getting Cors error in Laravel on some system 【发布时间】:2021-12-28 11:56:25 【问题描述】:

我在两个不同的域上托管 laravel (Laravel Framework 8.68.0) 和 Angular 应用程序,有时相同的代码可以正常工作,但有时会抛出此错误:

Access to XMLHttpRequest at from origin has been blocked by CORS policy Response to preflight request does'nt pass access control check : No Access Control Allow Origin header is present on the requested resource

Cors 中间件:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class CORS

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    
        $response = $next($request);
        $response->header('Access-Control-Allow-Origin', '*')->header('Access-Control-Allow-Headers', 'Content-type, X-Auth-Token, Authorization, Origin');
        return $response;
    

内核.php

   <?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel

    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\CORS::class,
        \App\Http\Middleware\TrustProxies::class,
        //\Fruitcake\Cors\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    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' => [
            // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    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,
        //'guest' => \App\Http\Middleware\CORS::class,
        //'cors' => \App\Http\Middleware\CORS::class,
    ];

api.php

Route::group(['middleware' => ['api'],'prefix' => 'auth'], function ($router) 
    Route::post('/login', [AuthController::class, 'login']);
    Route::post('/register', [AuthController::class, 'register']);
    Route::post('/logout', [AuthController::class, 'logout']);
    Route::post('/refresh', [AuthController::class, 'refresh']);
    Route::get('/user-profile', [AuthController::class, 'userProfile']);    
);

cors.php

return [

    /*
    |--------------------------------------------------------------------------
    | Cross-Origin Resource Sharing (CORS) Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your settings for cross-origin resource sharing
    | or "CORS". This determines what cross-origin operations may execute
    | in web browsers. You are free to adjust these settings as needed.
    |
    | To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    |
    */

    'paths' => ['api/*', 'sanctum/csrf-cookie'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => false,

];

路线服务商:

<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider

    /**
     * The path to the "home" route for your application.
     *
     * This is used by Laravel authentication to redirect users after login.
     *
     * @var string
     */
    public const HOME = '/home';

    /**
     * The controller namespace for the application.
     *
     * When present, controller route declarations will automatically be prefixed with this namespace.
     *
     * @var string|null
     */
    // protected $namespace = 'App\\Http\\Controllers';

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    
        $this->configureRateLimiting();

        $this->routes(function () 
            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));
        );
    

    /**
     * Configure the rate limiters for the application.
     *
     * @return void
     */
    protected function configureRateLimiting()
    
        RateLimiter::for('api', function (Request $request) 
            return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
        );
    

高度赞赏任何解决方案

谢谢。

【问题讨论】:

【参考方案1】:

除了您定义的 Cors 中间件, 另一个 Cors 中间件已在 Global Middlewares 中注册: \Fruitcake\Cors\HandleCors::class


    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
/* comment this out*/
 //       \Fruitcake\Cors\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

您忘记了自定义 Cors 的 Access-Control-Allow-Methods 标头。

        $response
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Headers', 'Content-type, X-Auth-Token, Authorization, Origin')
->header('Access-Control-Allow-Methods','POST, GET, OPTIONS');

【讨论】:

感谢您的回答,所以我不需要任何 \Fruitcake\Cors\HandleCors::class,我安装的这个包?问题是我跑的时候出现了 cors 错误 但是现在在注释掉 \Fruitcake\Cors\HandleCors::class 之后,我得到了 cors 错误并且错误是持久的 所以我猜你的自定义 Cors 类不起作用 但我没有使用这个我称之为自定义中间件的fruitcacke中间件,现在它正在从api路由中删除cors中间件 感谢您的帮助,我是否需要在其他地方做与 cors 设置相关的任何其他事情,或者现在这个应用程序也可以在服务器上正常运行

以上是关于在某些系统上的 Laravel 中出现 Cors 错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 Laravel Lighthouse 在 Laravel 7 中出现 CORS 错误

Laravel 上的 CORS(访问控制允许来源)

Ionic 3 - Laravel - 不向客户端发送允许 CORS 的标头

某些 Mac 机器浏览器上的 Angularjs CORS 问题

我在 Laravel 8 Cors 中做错了啥配置?

CORS、Laravel Valet 和 Socket.io