Laravel 5.1 API启用Cors

Leo*_*ato 26 php api cors laravel laravel-5.1

我已经找到了一些方法来启用laravel 5.1上的cors,我发现了一些类似的库:

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

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

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

如果某人已经在laravel 5.1上实施了CORS,我将非常感谢帮助......

Ale*_*dis 59

这是我的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;
    }

}
Run Code Online (Sandbox Code Playgroud)

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

protected $routeMiddleware = [
        //other middlewares
        'cors' => 'App\Http\Middleware\CORS',
    ];
Run Code Online (Sandbox Code Playgroud)

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

Route::get('example', array('middleware' => 'cors', 'uses' => 'ExampleController@dummy'));
Run Code Online (Sandbox Code Playgroud)

  • 请注意,对我来说它是5.6版本,我还需要在Kernel.php中添加`\ App\Http\Middleware\Cors :: class`,在`protected $ middleware`数组中.如果有人像我一样受苦,可以试试这个 (8认同)
  • @retrograde是的,如果你选择这个解决方案,你不必使用包. (6认同)
  • 只是为了澄清 - 这是问题中提到的包的替代方案吗? (4认同)
  • 这是非常好的解决方案,也是OPTIONS方法来检查Origin是否被允许 - 就像它在中间件中一样 - 但由于某种原因我无法在laravel 5.X中为POST方法运行 - 任何想法? (2认同)

Joe*_*mes 30

我总是使用简单的方法.只需在\public\index.php文件中添加以下行.您不必使用我认为的中间件.

header('Access-Control-Allow-Origin: *');  
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
Run Code Online (Sandbox Code Playgroud)

  • @EfriandikaPratama一遍又一遍地说同样的话并不能证明你的观点. (15认同)
  • 它不优雅 (12认同)
  • 如果您想为完整的应用程序启用CORS,这是很好的,但如果您想在某些路由上启用CORS则不适用.我认为使用中间件更有意义. (6认同)
  • @EfriandikaPratama为什么不呢?`index.php`文件正在所有HTTP请求上使用.所以这是一种简单易用的方式. (4认同)
  • 这简短而有趣,我认为当所有路由都已使用OAuth或JWT保护时,就不需要在中间件中进行保护。 (2认同)

Ris*_*abh 9

我正在使用Laravel 5.4并且遗憾的是,虽然接受的答案看起来很好,但对于请求之前的预检请求(例如PUTDELETE)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');
Run Code Online (Sandbox Code Playgroud)

我也为同样的目的编写了一个中间件,它看起来很相似但是尺寸更大,因为它试图更可配置并处理一系列条件:

<?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;
    }
}
Run Code Online (Sandbox Code Playgroud)

还写了一篇关于此的博文.


Tar*_*han 6

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

  1. 在将其添加为作曲家依赖项之后,请确保已发布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' => [],
    ];
    
    Run Code Online (Sandbox Code Playgroud)
  2. 此后,还有一个文档中未提及的步骤,您必须'Barryvdh\Cors\HandleCors'在App内核中添加CORS处理程序。我更喜欢在全局中间件堆栈中使用它。像这样

    /**
     * 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',
    
    ];
    
    Run Code Online (Sandbox Code Playgroud)

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

这应该使程序包与L5.1一起使用


saj*_*bat 6

对我来说,我把这些代码放在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");

Run Code Online (Sandbox Code Playgroud)