Laravel、AngularJS 和 CORS 的路由问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21559408/
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-09-14 08:58:36  来源:igfitidea点击:

Routing issue with Laravel, AngularJS and CORS

javascriptphpangularjslaravelcors

提问by Leon Revill

I have been searching far and wide for a solution to this problem.

我一直在寻找解决这个问题的方法。

I have an AngularJS web app with a Laravel 4 backend implementation as follows:

我有一个带有 Laravel 4 后端实现的 AngularJS Web 应用程序,如下所示:

http://app.mydomain.io/ = AngularJS web app
http://api.mydomain.io/ = Laravel Back-end

Within the routes.php file in Laravel I have the following PHP code to set the Access-Control headers:

在 Laravel 的 routes.php 文件中,我有以下 PHP 代码来设置访问控制标头:

header('Access-Control-Allow-Origin: http://app.mydomain.io');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');

I also have a route set-up for a login request as follows:

我还有一个登录请求的路由设置,如下所示:

Route::post('/login', function()
{
    $email = Input::get('email');
    $password = Input::get('password');
    if (Auth::attempt(array('email' => $email, 'password' => $password)))
    {
        return "Success!";
    } else {
        return "Fail!";
    }
});

In AngularJS I have a AuthService which looks like below:

在 AngularJS 中,我有一个 AuthService,如下所示:

app.factory('AuthService', ['$resource', '$q', '$cookieStore', function($resource, $q, $cookieStore) {
    var user = null;
    var Service = $resource('//api.mydomain.io/login/', {}, {});
    return {
        login: function(email, password) {
            var deferred = $q.defer();
            Service.save({email: email, password: password}, function(response) {
                $cookieStore.put('user', JSON.stringify(response));
                deferred.resolve(true);
            }, function(error) {
                deferred.reject(error);
            });
            return deferred.promise;
        }
    };
}]);

When this request is made I get the following:

提出此请求时,我得到以下信息:

XMLHttpRequest cannot load http://api.mydomain.io/login. Invalid HTTP status code 404

If I change the Laravel route and AngularJS service to use GET, everything works as expected. The problem stems from AngularJS .save() making a OPTIONS request instead of POST (I don't fully understand why).

如果我将 Laravel 路由和 AngularJS 服务更改为使用 GET,一切都会按预期进行。问题源于 AngularJS .save() 发出 OPTIONS 请求而不是 POST (我不完全明白为什么)。

Could anyone help me with the proper and best practice solution?

任何人都可以帮助我提供正确和最佳实践的解决方案吗?

Thank you!

谢谢!

回答by Leon Revill

The following solution worked:

以下解决方案有效:

Within filters.php add the following:

在 filters.php 中添加以下内容:

App::before(function($request)
{
    if (Request::getMethod() == "OPTIONS") {
        $headers = array(
            'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers'=> 'X-Requested-With, content-type',);
        return Response::make('', 200, $headers);
    }
});

And at the top of routes.php add the following:

并在 routes.php 的顶部添加以下内容:

header('Access-Control-Allow-Origin: http://app.mydomain.io');

Thanks to the Google Plus community! :)

感谢 Google Plus 社区!:)

Leon.

莱昂。

回答by himangshuj

In client side http://docs.angularjs.org/api/ng.$http

在客户端 http://docs.angularjs.org/api/ng.$http

you can try setting default "Setting HTTP Headers"

您可以尝试设置默认的“设置 HTTP 标头”

回答by jfornoff

I have used quite some time figuring this out and that is what i came up with:

我已经花了很长时间来弄清楚这一点,这就是我想出的:

Filters.php:

过滤器.php:

App::before(function($request)
{

    header('Access-Control-Allow-Origin: http://app.mydomain.io');
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization');

    // Pre-flight request handling, this is used for AJAX
    if($request->getRealMethod() == 'OPTIONS')
    {
        Log::debug('Pre flight request from Origin'.$rq_origin.' received.');
        // This is basically just for debug purposes
        return Response::json(array('Method' => $request->getRealMethod()), 200);
    }
});

App.js (Frontend):

App.js(前端):

app.config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.useXDomain = true;
    $httpProvider.defaults.withCredentials = true;
    delete $httpProvider.defaults.headers.common['X-Requested-With'];

}]);

}]);

Also note that there is a bug with self-signed SSL certificates in Chrome and CORS request, i will provide a link if you are interested in that.

另请注意,Chrome 和 CORS 请求中存在自签名 SSL 证书的错误,如果您对此感兴趣,我将提供一个链接。

So be advised to use Firefox while debugging (or DevHTTPClient on Chrome works fine for me).

因此建议在调试时使用 Firefox(或 Chrome 上的 DevHTTPClient 对我来说很好用)。

Cheers!

干杯!

回答by iongraphix

Try this piece for newer versions of Laravel (5+)

试试这篇文章以获得更新版本的 Laravel (5+)

public function handle($request, Closure $next)
{
    $method = $request->method();
    if($method == "OPTIONS"){
       return response('It\'s supported. Relax!', 200); 
    }
    return $next($request);
}