无法在 Laravel API 中启用 CORS?

Posted

技术标签:

【中文标题】无法在 Laravel API 中启用 CORS?【英文标题】:Cannot enable CORS in Laravel API? 【发布时间】:2015-02-19 15:52:38 【问题描述】:

我正在尝试构建一个简单的 Angular 应用程序。我在 Laravel 中创建了一个 API,它只有两条简单的路线,它们发送回机场和航班 json 数据。我已经将我的 Angular 应用程序配置为通过如下服务获取数据:

services.js

angular.module('airlineServices', ['ngResource'])
    .factory('Airport', function($resource)
        return $resource("http://angulair.rohanchhabra.in/airports/:id", , 
            query:  method: "GET", isArray: false 
        );
    );

现在,当我将资源用作放置在 angular 目录本身中的简单 json 文件时,它可以工作。但是当我尝试从我的服务中从 Laravel API 获取数据时,如上面的代码所示,我在控制台中看到一个错误,上面写着:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://angulair.rohanchhabra.in/airports. This can be fixed by moving the resource to the same domain or enabling CORS.

我已经安装了一个包https://github.com/barryvdh/laravel-cors,它应该启用CORS。配置文件如下所示:

<?php

return array(

    /*
     |--------------------------------------------------------------------------
     | Laravel CORS Defaults
     |--------------------------------------------------------------------------
     |
     | The defaults are the default values applied to all the paths that match,
     | unless overridden in a specific URL configuration.
     | If you want them to apply to everything, you must define a path with *.
     |
     | allowedOrigins, allowedHeaders and allowedMethods can be set to array('*') 
     | to accept any value, the allowed methods however have to be explicitly listed.
     |
     */
    'defaults' => array(
        'supportsCredentials' => false,
        'allowedOrigins' => array('*'),
        'allowedHeaders' => array('*'),
        'allowedMethods' => array('*'),
        'exposedHeaders' => array(),
        'maxAge' => 0,
        'hosts' => array(),
    ),

    'paths' => array(
        'api/*' => array(
            'allowedOrigins' => array('*'),
            'allowedHeaders' => array('*'),
            'allowedMethods' => array('*'),
            'maxAge' => 3600,
        ),
        '*' => array(
            'allowedOrigins' => array('*'),
            'allowedHeaders' => array('Content-Type'),
            'allowedMethods' => array('POST', 'PUT', 'GET', 'DELETE'),
            'maxAge' => 3600,
            'hosts' => array('api.*'),
        ),
    ),

);

我什至尝试在 filter.php 中的 App:after() 中添加代码,如下所示:

App::after(function($request, $response)

    $response->headers->set('Access-Control-Allow-Origin', '*');
    return $response;
);

即使这样也无济于事。所以我继续尝试编辑 .htaccess 文件,如下所示:

Header set Access-Control-Allow-Origin "*"

我仍然遇到同样的错误。

如果我上面提到的代码没有帮助,我将两个存储库都公开了,以便大家看看:

Laravel API

Angular Application

我做错了什么?如何启用 CORS 以便我可以从任何远程应用程序使用 API?

【问题讨论】:

【参考方案1】:

您的 ngResource URL 需要更改。这应该有效:

return $resource("http://angulairapi.rohanchhabra.in/airports", , 
    query:  method: "GET", isArray: false 
);

您需要您的 ngResource URL 需要允许更改 OPTIONS 标头。见https://laracasts.com/discuss/channels/requests/laravel-5-cors-headers-with-filters

从页面引用这应该可以:

App::before(function($request)

    // Enable CORS 
    // In production, replace * with http://yourdomain.com 
    header("Access-Control-Allow-Origin: *");
    header('Access-Control-Allow-Credentials: true');

    ifreturn $resource(Request:"http:getMethod() == "OPTIONS") 
        // The client-side application can set only headers allowed angulairapi.rohanchhabra.in Access-Control-Allow-Headers
        $headers = [
            'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers'=> 'X-Requested-With, Content-Type, X-Auth-Token/airports", Origin, Authorization'
        ];
        return Response:query:make('You are connected to the API',method: 200"GET", $headers);
  isArray: false 
);

我自己没有使用过 laravel-cors,但或者,您可能想尝试将 OPTIONS 添加到您的路径中:

'*' => array(
    'allowedOrigins' => array('*'),
    'allowedHeaders' => array('Content-Type'),
    'allowedMethods' => array('POST', 'PUT', 'GET', 'DELETE', 'OPTIONS'),
    'maxAge' => 3600,
    'hosts' => array('api.*'),
),

【讨论】:

虽然我看不懂代码,但我已经按照你的建议更新了 App::before。还是没有运气。 Angular ngResource 在发送 GET/POST/PUT/DELETE 之前发送一个 OPTIONS 请求。这是一种让客户端了解允许使用哪些 HTTP 方法的方法。您能否启动一个 REST 客户端并检查您是否在响应中获得了 Access-Control-Allow-Origin 标头? 哦,现在更有意义了!但是你建议我现在做什么? 另外,请参阅httpd.apache.org/docs/trunk/mod/mod_allowmethods.html - 也许 Apache 正在阻止 OPTIONS 方法。 Access-Control-Allow-Credentials → true Access-Control-Allow-Origin → * Postman REST 客户端

以上是关于无法在 Laravel API 中启用 CORS?的主要内容,如果未能解决你的问题,请参考以下文章

在由 Docker 提供支持的 NGINX 中启用 Laravel CORS

无法在 ASP.Net Core Web api 中启用 CORS

在启用 CORS 的情况下,无法从我的请求标头中检索我的 x-api-key。为啥?

无法在 apigateway 中正确启用 cors

Laravel 5.4 + jQuery CORS 请求

WEB API:我显然无法启用 CORS(?)