CORS problem with the PhoneGap Angular and Rails application

advertisements

Getting started with PhoneGap, using yeoman, bower and grunt setup with Angular. I'm trying to get a response from my Rails API and always get XMLHttpRequest cannot load http://localhost:3000/api/v1/sessions. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access.

I've tried what feels like every solution in the book, but can't get this working.

Here's the necessary code:

class Api::V1::BaseController < ActionController::Base
  respond_to :json

  protect_from_forgery with: :null_session

  before_filter :set_cors_headers
  before_filter :cors_preflight

  def set_cors_headers
    headers['Access-Control-Allow-Origin'] = AppConfig.client['origin']
    headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
    headers['Access-Control-Allow-Headers'] = '*'
    headers['Access-Control-Max-Age'] = "3628800"
  end

  def cors_preflight
    head(:ok) if request.method == :options
  end
end

In my app_config.yml file:

defaults: &defaults
  client:
    origin: http://localhost:9000

development:
  <<: *defaults

test:
  <<: *defaults

production:
  <<: *defaults

I'm loading this in an initializer, app_config.rb:

require 'ostruct'
require 'yaml'

config = YAML.load_file(File.join(Rails.root, 'config', 'app_config.yml')) || {}
AppConfig = OpenStruct.new(config[Rails.env] || {})

I tried using the Rack CORS gem as well, and have this in my application.rb:

module MyApp
  class Application < Rails::Application
    config.middleware.use Rack::Cors do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options, :delete]
      end
    end
  end
end

Using Rails 4.1.


To use CORS within Angular, we need to tell Angular that we’re using CORS. We use the .config() method on our Angular app module to set two options. First, we need to tell Angular to use the XDomain, and we must remove the X-Requested-With header from all of our requests.

angular.module('myApp')
   .config(function($httpProvider) {
     $httpProvider.defaults.useXDomain = true;
       delete $httpProvider.defaults.headers
        .common['X-Requested-With'];
});

Now we’re ready to make CORS requests.