4

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:

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:

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:

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).

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

Thank you!

1

4 Answers 4

7

The following solution worked:

Within filters.php add the following:

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:

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

Thanks to the Google Plus community! :)

Leon.

Sign up to request clarification or add additional context in comments.

1 Comment

You Sir, just saved me another hour of searching!
0

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

you can try setting default "Setting HTTP Headers"

Comments

0

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

Filters.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.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.

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

Cheers!

Comments

0

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

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.