Laravel 5.1 API 启用 Cors

问题描述 投票:0回答:9

我专门寻找了一些在 Laravel 5.1 上启用 cors 的方法,并且找到了一些库,例如:

https://github.com/neomerx/cors-Illuminate

https://github.com/barryvdh/laravel-cors

但是他们都没有专门针对 Laravel 5.1 的实现教程,我尝试配置但它不起作用。

如果有人已经在 Laravel 5.1 上实现了 CORS,我将不胜感激......

php laravel api laravel-5 cors
9个回答
93
投票

这是我的 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)
    {

        header("Access-Control-Allow-Origin: *");

        // ALLOW OPTIONS METHOD
        $headers = [
            'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin'
        ];
        if($request->getMethod() == "OPTIONS") {
            // The client-side application can set only headers allowed in Access-Control-Allow-Headers
            return Response::make('OK', 200, $headers);
        }

        $response = $next($request);
        foreach($headers as $key => $value)
            $response->header($key, $value);
        return $response;
    }

}

要使用 CORS 中间件,您必须首先在 app\Http\Kernel.php 文件中注册它,如下所示:

protected $routeMiddleware = [
        //other middlewares
        'cors' => 'App\Http\Middleware\CORS',
    ];

然后你就可以在你的路线中使用它了

Route::get('example', array('middleware' => 'cors', 'uses' => 'ExampleController@dummy'));
编辑:在 Laravel ^8.0 中,您必须导入控制器的名称空间并使用如下所示的类:
use App\Http\Controllers\ExampleController;

Route::get('example', [ExampleController::class, 'dummy'])->middleware('cors');

50
投票

我总是使用简单的方法。只需将以下行添加到

\public\index.php
文件中即可。我认为你不必使用中间件。

header('Access-Control-Allow-Origin: *');  
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');

14
投票

我正在使用 Laravel 5.4,不幸的是,尽管接受的答案似乎很好,但对于预检请求(如

PUT
DELETE
),其前面将有一个
OPTIONS
请求,指定
$routeMiddleware
数组中的中间件(并且除非您也为
OPTIONS
定义了一个路由处理程序,否则在路由定义文件中使用它是行不通的。这是因为如果没有
OPTIONS
路由,Laravel 将在没有 CORS 标头的情况下内部响应该方法。

因此,简而言之,要么在

$middleware
数组中定义中间件,该数组为所有请求全局运行,或者如果您在
$middlewareGroups
$routeMiddleware
中执行此操作,则还为
OPTIONS
定义一个路由处理程序。这可以这样做:

Route::match(['options', 'put'], '/route', function () {
    // This will work with the middleware shown in the accepted answer
})->middleware('cors');

我还出于相同的目的编写了一个中间件,它看起来相似,但尺寸更大,因为它试图更具可配置性并处理一堆条件:

<?php

namespace App\Http\Middleware;

use Closure;

class Cors
{
    private static $allowedOriginsWhitelist = [
      'http://localhost:8000'
    ];

    // All the headers must be a string

    private static $allowedOrigin = '*';

    private static $allowedMethods = 'OPTIONS, GET, POST, PUT, PATCH, DELETE';

    private static $allowCredentials = 'true';

    private static $allowedHeaders = '';

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
      if (! $this->isCorsRequest($request))
      {
        return $next($request);
      }

      static::$allowedOrigin = $this->resolveAllowedOrigin($request);

      static::$allowedHeaders = $this->resolveAllowedHeaders($request);

      $headers = [
        'Access-Control-Allow-Origin'       => static::$allowedOrigin,
        'Access-Control-Allow-Methods'      => static::$allowedMethods,
        'Access-Control-Allow-Headers'      => static::$allowedHeaders,
        'Access-Control-Allow-Credentials'  => static::$allowCredentials,
      ];

      // For preflighted requests
      if ($request->getMethod() === 'OPTIONS')
      {
        return response('', 200)->withHeaders($headers);
      }

      $response = $next($request)->withHeaders($headers);

      return $response;
    }

    /**
     * Incoming request is a CORS request if the Origin
     * header is set and Origin !== Host
     *
     * @param  \Illuminate\Http\Request  $request
     */
    private function isCorsRequest($request)
    {
      $requestHasOrigin = $request->headers->has('Origin');

      if ($requestHasOrigin)
      {
        $origin = $request->headers->get('Origin');

        $host = $request->getSchemeAndHttpHost();

        if ($origin !== $host)
        {
          return true;
        }
      }

      return false;
    }

    /**
     * Dynamic resolution of allowed origin since we can't
     * pass multiple domains to the header. The appropriate
     * domain is set in the Access-Control-Allow-Origin header
     * only if it is present in the whitelist.
     *
     * @param  \Illuminate\Http\Request  $request
     */
    private function resolveAllowedOrigin($request)
    {
      $allowedOrigin = static::$allowedOrigin;

      // If origin is in our $allowedOriginsWhitelist
      // then we send that in Access-Control-Allow-Origin

      $origin = $request->headers->get('Origin');

      if (in_array($origin, static::$allowedOriginsWhitelist))
      {
        $allowedOrigin = $origin;
      }

      return $allowedOrigin;
    }

    /**
     * Take the incoming client request headers
     * and return. Will be used to pass in Access-Control-Allow-Headers
     *
     * @param  \Illuminate\Http\Request  $request
     */
    private function resolveAllowedHeaders($request)
    {
      $allowedHeaders = $request->headers->get('Access-Control-Request-Headers');

      return $allowedHeaders;
    }
}

还为此写了一篇博客文章


11
投票

对我来说,我将此代码放入

public\index.php
文件中。它对于所有 CRUD 操作都运行良好。

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS, post, get');
header("Access-Control-Max-Age", "3600");
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
header("Access-Control-Allow-Credentials", "true");


10
投票

barryvdh/laravel-cors 与 Laravel 5.1 完美配合,只需几个关键点即可启用它。

  1. 将其添加为 Composer 依赖项后,请确保您已发布 CORS 配置文件并根据需要调整 CORS 标头。这是我在 app/config/cors.php

    中的样子
    <?php
    
    return [
    
        'supportsCredentials' => true,
        'allowedOrigins' => ['*'],
        'allowedHeaders' => ['*'],
        'allowedMethods' => ['GET', 'POST', 'PUT',  'DELETE'],
        'exposedHeaders' => ['DAV', 'content-length', 'Allow'],
        'maxAge' => 86400,
        'hosts' => [],
    ];
    
  2. 在此之后,还有文档中未提及的一步,您必须在 App 内核中添加 CORS 处理程序

    'Barryvdh\Cors\HandleCors'
    。我更喜欢在全局中间件堆栈中使用它。像这样

    /**
     * The application's global HTTP middleware stack.
     *
     * @var array
     */
    protected $middleware = [
        'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
        'Illuminate\Cookie\Middleware\EncryptCookies',
        'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
        'Illuminate\Session\Middleware\StartSession',
        'Illuminate\View\Middleware\ShareErrorsFromSession',
    
        'Barryvdh\Cors\HandleCors',
    
    ];
    

    但是您可以将其用作路由中间件并放置在特定路由上。

这应该使该包适用于 L5.1


2
投票

Laravel 8

创建中间件

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class CorsMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        return $next($request)
            ->header('Access-Control-Allow-Origin', config('cors.allowed_origins')) 
            ->header('Access-Control-Allow-Methods', config('cors.allowed_methods'))
            ->header('Access-Control-Allow-Headers',config('cors.allowed_headers'));
    }
}

配置/cors.php

return [
    'paths' => [
        'api/*', 
        'admin/api/*', 
        'sanctum/csrf-cookie'
    ],
    'allowed_methods' => [ //'GET, POST, PUT, PATCH, DELETE, OPTIONS'
        'GET', 
        'POST', 
        'PUT', 
        'PATCH', 
        'DELETE', 
        'OPTIONS'
    ],
    'allowed_origins' => ['*'],
    'allowed_origins_patterns' => [],
    'allowed_headers' => [//  'Content-Type, Authorization, Accept'
        'Content-Type', 
        'Authorization', 
        'Accept'
    ],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => true,
];

kernel.php 用于 http

    protected $middleware = [
        ... ,
        \App\Http\Middleware\CorsMiddleware::class,  // Cors middlewate
    ];


2
投票

如果您没有通过函数闭包或控制器操作从路线返回响应,那么它将不起作用。

不起作用

控制器动作

Route::post('login','AuthController@login');

class AuthController extends Controller {

     ...

     public function login() {
          dd(['key' => 'value']);
          //OR
          die(['key' => 'value']);
          //OR
          print_r(['key' => 'value');
          exit();
     }

     ...

}

有效!

控制器动作

Route::post('login','AuthController@login');

class AuthController extends Controller {

     ...

     public function login() {
          return response()->json(['key' => 'value'], 200);
          // OR
          return ['key' => 'value'];
          // OR
          $data = ['key' => 'value'];
          return $data;
     }

     ...

}

测试 CORS

Chrome -> 开发者工具 -> 网络选项卡

如果出现任何问题,那么您的响应标头将不会出现在此处。


1
投票

https://github.com/fruitcake/laravel-cors

使用这个库。请按照本存储库中提到的说明进行操作。

请记住不要在 CORS URL 中使用

dd()
die()
,因为此库将无法工作。始终将 return 与 CORS URL 一起使用。

谢谢


0
投票

只需将其用作中间件

<?php

namespace App\Http\Middleware;

use Closure;

class CorsMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        $response->header('Access-Control-Allow-Origin', '*');
        $response->header('Access-Control-Allow-Methods', '*');

        return $response;
    }
}

并在此路径上的内核文件中注册中间件

app/Http/Kernel.php
在您喜欢的组中,一切都会好起来的

© www.soinside.com 2019 - 2024. All rights reserved.