Lampbo
Lampbo

Reputation: 121

Rails 3 and Angularjs Origin http://localhost is not allowed by Access-Control-Allow-Origin.

First, let me say that I have tried a ton of solutions that have been posted here. None of them seem to work for me. I realize that my problem is stemming from CORS and my rails app's inability to handle the correctly. However, I'm not quite sure how to rectify this issue. I'm hoping someone here can shed some light on this issue.

Relevant Code snippets:

Rails application_controler.rb

class ApplicationController < ActionController::Base
protect_from_forgery
#before_filter :cors_preflight_check
before_filter :allow_cross_domain_access
after_filter :cors_set_access_control_headers

# For all responses in this controller, return the CORS access control headers.

def cors_set_access_control_headers
  headers['Access-Control-Allow-Origin'] = '*'
  headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
  headers['Access-Control-Max-Age'] = "1728000"
end

def cors_preflight_check
  if request.method == :options
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
    headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-Prototype-Version'
    headers['Access-Control-Max-Age'] = '1728000'
    render :text => '', :content_type => 'text/plain'
  end
end

def allow_cross_domain_access
    headers['Access-Control-Allow-Origin'] = '*'# http://localhost:9000
    headers['Access-Control-Allow-Headers'] = 'GET, POST, PUT, DELETE, OPTIONS'
    headers['Access-Control-Allow-Methods'] = %w{Origin Accept Content-Type X-Requested-With X-CSRF-Token}.join(',')
    headers['Access-Control-Max-Age'] = '1728000'
end 
end

Angular App.js

]).config(function($httpProvider){
   delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
function loginCtrl ($scope,$http) {
$scope.master = {};

$scope.isUnchanged = function(user) {
    return angular.equals(user, $scope.master);
};

$scope.login = function (user) {
    $http({
        method: 'POST', 
        /*url: 'http://localhost/test/quote.php',*/
        url: 'http://localhost:3000/api/sessions/',
        data: user
    }).success(function(data)
    {
        alert("call phonegap store data function:" + data.access_token)
    }).error(function (data, status, headers, config) {
        alert("error" )
    }); 
};

}

Error message from chorme

OPTIONS http://localhost:3000/api/sessions/ 404 (Not Found) angular.js:6730
OPTIONS http://localhost:3000/api/sessions/ Origin http://localhost is not allowed by Access-Control-Allow-Origin. angular.js:6730
XMLHttpRequest cannot load http://localhost:3000/api/sessions/. Origin http://localhost is not allowed by Access-Control-Allow-Origin. 

Error message from rails server

Started OPTIONS "/api/sessions/" for 127.0.0.1 at 2013-11-03 22:30:54 -0500

ActionController::RoutingError (uninitialized constant SessionsController):
activesupport (3.2.13) lib/active_support/inflector/methods.rb:230:in 
`block in constantize'               
activesupport (3.2.13) lib/active_support/inflector/methods.rb:229:in `each'
activesupport (3.2.13) lib/active_support/inflector/methods.rb:229:in `constantize'
actionpack (3.2.13) lib/action_dispatch/routing/route_set.rb:69:in `controller    
_reference' .....


 ....C:/Ruby/lib/ruby/2.0.0/webrick/httpserver.rb:138:in `service'
 C:/Ruby/lib/ruby/2.0.0/webrick/httpserver.rb:94:in `run'
 C:/Ruby/lib/ruby/2.0.0/webrick/server.rb:295:in `block in start_thread'


 Rendered C:/Ruby/lib/ruby/gems/2.0.0/gems/actionpack-    
 3.2.13/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within 
  rescues/layout (0.0ms)

Any help with this will be greatly appreciated!

Upvotes: 2

Views: 3392

Answers (3)

Will
Will

Reputation: 271

I can see that you found a solution to your problem, but I just wanted to point out that also your allow-headers and allow-methods are mixed up in your allow_cross_domain_access method.

You have:

def allow_cross_domain_access
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Headers'] = 'GET, POST, PUT, DELETE, OPTIONS'
    headers['Access-Control-Allow-Methods'] = %w{Origin Accept Content-Type X-Requested-With X-CSRF-Token}.join(',')
    headers['Access-Control-Max-Age'] = '1728000'
end 

Should be:

def allow_cross_domain_access
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
    headers['Access-Control-Allow-Headers'] = %w{Origin Accept Content-Type X-Requested-With X-CSRF-Token}.join(',')
    headers['Access-Control-Max-Age'] = '1728000'
end 

Hope that helps :)

Upvotes: 0

Lampbo
Lampbo

Reputation: 121

I figured it out.

    after_filter :cors_set_access_control_headers

# For all responses in this controller, return the CORS access control headers.

def cors_set_access_control_headers
        headers['Access-Control-Allow-Origin'] = '*'
        headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
        headers['Access-Control-Allow-Headers'] = %w{Origin Accept Content-Type X-Requested-With X-CSRF-Token}.join(',')
        headers['Access-Control-Max-Age'] = "1728000"
end

I placed the code above in my base controller that all of my api controllers inherit from. The issue was copying and pasting solutions. The ALLOW-headers and Allow-Methods values were inverted. That fixed it.

Upvotes: 3

moritz
moritz

Reputation: 25757

So if I understand correctly, your rails app is running on localhost:3000, serving an angular app which in turn requests from localhost:80. In that case, you would need Access-Control-Allow-Origin on localhost:80.

Upvotes: 0

Related Questions