2015-10-12 75 views
11

我尋找一些方法來啓用laravel 5.1特別CORS,我已經發現了一些類似的庫:Laravel 5.1 API允許一個Cors

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

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

,但他們都沒有一個專門針對Laravel 5.1的實現教程,我試圖配置,但它不起作用。

如果laravel 5.1已經有人實現CORS我會的幫助表示感謝......

+0

Barryvdh的是Laravel 5,真的它應該開箱即用5.1。你試過了嗎? – Dencker

+0

是的,我嘗試過,但我仍然收到以下消息(這是一個角度前端) XMLHttpRequest無法加載http://api.address.com。請求的資源上沒有「Access-Control-Allow-Origin」標題。原因'http://127.0.0.1:8080'因此不被允許訪問。 但我已經添加了對CORS的本地地址文件 'supportsCredentials'=>真實, 'allowedOrigins'=> [ 'http://127.0.0.1:8080'], 'allowedHeaders'=> [ '''', 'allowedMethods'=> ['GET','POST','PUT','DELETE'], 'exposedHeaders'=> [], 'maxAge'=> 0, 'hosts' => [], –

+0

你收到哪條消息? – Dencker

回答

23

這裏是我的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中間件你必須先註冊設備您的應用程序\ HTTP \ Kernel.php文件是這樣的:

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

然後你就可以在你的路由使用它

​​
+0

Works在Apache但不是IIS :( – suncoastkid

+2

只是爲了澄清 - 這是在問題中提到的軟件包的替代? – retrograde

+3

@retrograde是啊如果你選擇這個解決方案,你不必使用一個包 –

8

我總是用一種簡單的方法。只需將以下行添加到\public\index.php文件。您不必使用我認爲的中間件。

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

這不是優雅 –

+1

@EfriandikaPratama爲什麼不呢?所有HTTP請求都使用'index.php'文件。所以這是一個簡單和用戶友好的方式。 –

+0

這不是優雅。如果你把代碼放在中間件中會更優雅。 –

2

barryvdh/laravel-cors與Laravel 5.1完美搭配,只需幾個關鍵點即可實現。

  1. 將其作爲一個作曲家的依賴後,請確保您已發佈的CORS配置文件,只要你想他們調整CORS標頭。下面是我如何看待在應用程序/配置/ cors.php

    <?php 
    
    return [ 
    
        'supportsCredentials' => true, 
        'allowedOrigins' => ['*'], 
        'allowedHeaders' => ['*'], 
        'allowedMethods' => ['GET', 'POST', 'PUT', 'DELETE'], 
        'exposedHeaders' => ['DAV', 'content-length', 'Allow'], 
        'maxAge' => 86400, 
        'hosts' => [], 
    ]; 
    
  2. 在此之後,有一個步驟,這不是在文檔中提到的,你必須添加CORS處理'Barryvdh\Cors\HandleCors'在App內核。我更喜歡在全局中間件堆棧中使用它。像這樣

    /** 
    * 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

1

我使用Laravel 5.4和包裝工作,遺憾的是,儘管接受的答案似乎罰款,對預檢要求(如PUTDELETE),將通過前面OPTIONS請求,指定$routeMiddleware數組中的中間件(並在路由定義文件中使用該數組)將不起作用,除非您還爲OPTIONS定義了路由處理程序。這是因爲沒有OPTIONS路線Laravel將internally respond到沒有CORS標題的那個方法。

因此,在短期或者定義其全局運行所有請求,或者如果你這樣做是在$middlewareGroups$routeMiddleware隨後還定義路由處理程序OPTIONS$middleware數組中的中間件。這是可以做到這樣的:

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

此外還寫了一個blog post這個。