php Laravel 5.1 API 启用 Cors

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33076705/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:22:13  来源:igfitidea点击:

Laravel 5.1 API Enable Cors

phpapilaravelcorslaravel-5.1

提问by Leonardo Lobato

I've looked for some ways to enable cors on laravel 5.1 specifically, I have found some libs like:

我已经寻找了一些在 laravel 5.1 上启用 cors 的方法,我发现了一些库,例如:

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

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

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

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

but none of them has a implementation tutorial specifically to Laravel 5.1, I tried to config but It doesn't work.

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

If someone already implemented CORS on laravel 5.1 I would be grateful for the help...

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

回答by Alex Kyriakidis

Here is my CORS middleware:

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

}

To use CORS middleware you have to register it first in your app\Http\Kernel.php file like this:

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

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

Then you can use it in your routes

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

Route::get('example', array('middleware' => 'cors', 'uses' => 'ExampleController@dummy'));

回答by Joel James

I always use an easy method. Just add below lines to \public\index.phpfile. You don't have to use a middleware I think.

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

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

回答by Rishabh

I am using Laravel 5.4 and unfortunately although the accepted answer seems fine, for preflighted requests (like PUTand DELETE) which will be preceded by an OPTIONSrequest, specifying the middleware in the $routeMiddlewarearray (and using that in the routes definition file) will not work unless you define a route handler for OPTIONSas well. This is because without an OPTIONSroute Laravel will internally respondto that method without the CORS headers.

我正在使用 Laravel 5.4,不幸的是,虽然接受的答案看起来不错,但对于预检请求(如PUTDELETE),它将以OPTIONS请求$routeMiddleware开头,指定数组中的中间件(并在路由定义文件中使用它)将不起作用,除非您也定义一个路由处理程序OPTIONS。这是因为没有OPTIONS路由 Laravel 将在内部响应没有 CORS 标头的方法。

So in short either define the middleware in the $middlewarearray which runs globally for all requests or if you're doing it in $middlewareGroupsor $routeMiddlewarethen also define a route handler for OPTIONS. This can be done like this:

所以简而言之,要么在$middleware数组中定义中间件,该中间件为所有请求全局运行,或者如果您正在执行此操作,$middlewareGroups或者$routeMiddleware还为OPTIONS. 这可以像这样完成:

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

I also wrote a middleware for the same purpose which looks similar but is larger in size as it tries to be more configurable and handles a bunch of conditions as well:

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

<?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;
    }
}

Also written a blog poston this.

还写了一篇关于此的博客文章

回答by Tariq Khan

barryvdh/laravel-corsworks perfectly with Laravel 5.1 with just a few key points in enabling it.

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

  1. After adding it as a composer dependency, make sure you have published the CORS config file and adjusted the CORS headers as you want them. Here is how mine look in app/config/cors.php

    <?php
    
    return [
    
        'supportsCredentials' => true,
        'allowedOrigins' => ['*'],
        'allowedHeaders' => ['*'],
        'allowedMethods' => ['GET', 'POST', 'PUT',  'DELETE'],
        'exposedHeaders' => ['DAV', 'content-length', 'Allow'],
        'maxAge' => 86400,
        'hosts' => [],
    ];
    
  2. After this, there is one more step that's not mentioned in the documentation, you have to add the CORS handler 'Barryvdh\Cors\HandleCors'in the App kernel. I prefer to use it in the global middleware stack. Like this

    /**
     * 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',
    
    ];
    

    But its up to you to use it as a route middleware and place on specific routes.

  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. 在此之后,还有一个文档中没有提到的步骤,您必须'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',
    
    ];
    

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

This should make the package work with L5.1

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

回答by sajad Haibat

For me i put this codes in public\index.phpfile. and it worked just fine for all CRUD operations.

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

回答by Indrasinh Bihola

After wasting a lot of time I finally found this silly mistake which might help you as well.

在浪费了很多时间之后,我终于找到了这个愚蠢的错误,它也可能对您有所帮助。

If you can't return response from your route either through function closure or through controller action then it won't work.

如果您无法通过函数闭包或控制器操作从您的路由返回响应,那么它将无法工作。

Example:

例子:

Closure

关闭

Route::post('login', function () {
    return response()->json(['key' => 'value'], 200); //Make sure your response is there.
});

Controller Action

控制器动作

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

class AuthController extends Controller {

     ...

     public function login() {
          return response()->json(['key' => 'value'], 200); //Make sure your response is there.
     }

     ...

}

Test CORS

测试 CORS

Chrome -> Developer Tools -> Network tab

Chrome -> 开发者工具 -> 网络标签

enter image description here

在此处输入图片说明

If anything goes wrong then your response headers won't be here.

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

回答by adnan ahmady

just use this as a middleware

只需将其用作中间件

<?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;
    }
}

and register the middleware in your kernel file on this path app/Http/Kernel.phpin which group that you prefer and everything will be fine

并在您app/Http/Kernel.php喜欢的组中的此路径上的内核文件中注册中间件,一切都会好起来的