26

I wanted to implement CORS in my rails application, so I googled rack-cors gem for it. And I did everything as was said in README, that is updated Gemfile accordingly and updated application.rb like this:

module YourApp
  class Application < Rails::Application

    # ...

    config.middleware.use Rack::Cors do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options]
      end
    end

  end
end

But it didn't work. No matter what I did, in the browser console I kept getting message:
XMLHttpRequest cannot load https://somewebsite.com. Origin http://0.0.0.0:3000 is not allowed by Access-Control-Allow-Origin.

After reading this blogpost and issue on github, I realized that maybe position of rack-cors middleware in the middleware stack matters. So I did as was told in the github issue:

module YourApp
  class Application < Rails::Application

    # ...

    config.middleware.insert 0, Rack::Cors do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options]
      end
    end

  end
end

After that, when I run rake middleware rack-cors is really at the top of the stack.
But It still just simply won't work. I keep getting the same error. Anyone, please help.

Prostakov
  • 910
  • 1
  • 12
  • 22
  • I know it's obvious, but did you make sure to restart the rails server? Since this is part of initialization it won't take effect until a restart. – clexmond Aug 30 '13 at 17:39
  • 1
    Yes, I restarted the server lots of times. – Prostakov Aug 30 '13 at 17:47
  • The problem is that it is not anything supernatural, just to get this gem working. Just driving me insane... – Prostakov Aug 30 '13 at 17:49
  • _After reading this blogpost_ link changed, is now at http://www.dougwaltman.com/blog/2013/getting-cors-working-in-ruby-on-rails – Tom Hundt Apr 26 '16 at 22:47
  • I ran into this issue with Rails 4.2.4, and fixed it by making sure `origins '*'` is set, as well as adding Rack::Cors with `insert_before 0`, as well as adding routes for OPTIONS calls, like this: `match 'users', to: 'users#index', via: [:options]` on top of the regular routes – Tilo Aug 12 '16 at 18:44

6 Answers6

21

I ran into the same problem with heroku. I found this blog with the same rack-cors issue.

Just moved the use Rack::Cors to config.ru, redeployed to heroku and it works.

require ::File.expand_path('../config/environment',  __FILE__)
run Rails.application

require 'rack/cors'
use Rack::Cors do

  # allow all origins in development
  allow do
    origins '*'
    resource '*', 
        :headers => :any, 
        :methods => [:get, :post, :delete, :put, :options]
  end
end
dcunited001
  • 501
  • 3
  • 6
  • 1
    That **DO** work. And as of july 7th 2014, that's **the very only way** to make it work (or you can spend 2/3 hours landing on every solution available on google…). thx – Ben Jul 03 '14 at 08:57
  • make sure you have this `require 'rack/cors'` – Saad Masood Aug 18 '14 at 07:02
  • This works great but it doesn't seem to work on development(for our app at least) So make sure you test it out on staging or other production like server if it doesn't work on development for you either. – Marius Pop Sep 10 '14 at 19:01
  • 2021 and this is still the solution for a heroku Rails API with React SPA app. – jmoon90 Oct 01 '21 at 00:51
13

There is a new issue thread for the heroku solution

Instead of using

config.middleware.use Rack::Cors do

try

config.middleware.insert_before ActionDispatch::Static, Rack::Cors do

That worked for me.

farofeiro
  • 185
  • 6
  • This seems to be a Rails version thing. I found I had to use the first code snippet in the answer above in Rails 3.2 and the second snippet in Rails 4.1. – David Tuite Jun 25 '14 at 11:26
  • 1
    both worked for me, rails 4.1. This thread is priceless, compared to the tons of crap that can be found about this topic on the web – Ben Jul 03 '14 at 09:04
3

Here's how I fixed mine:

You just need to un-comment the Rack CORS gem in your Gemfile (if it's there) or just add it:

gem 'rack-cors'

And then run the code below to install the gem:

bundle install

Create a config/initializers/cors.rb file and put the code below into it:

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'
    resource '*', headers: :any, methods: [:get, :post, :patch, :put]
  end
end

OR

Put the code below in config/application.rb of your Rails application. For example, this will allow GET, POST or OPTIONS requests from any origin on any resource:

module YourApp
  class Application < Rails::Application
    # ...
    
    # For Rails 5 Appications

    config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins '*'
        resource '*', headers: :any, methods: [:get, :post, :options]
      end
    end

    # For Rails 3/4 Applications

    config.middleware.insert_before 0, "Rack::Cors" do
      allow do
        origins '*'
        resource '*', headers: :any, methods: [:get, :post, :options]
      end
    end
  end
end

Setting origins to '*' should be alright for development, but keep in mind that if you deploy to production you’ll want to change this value to match your front-end’s URI for security reasons.

Note: If you're running Rails, updating in config/application.rb or 'config/initializers/cors.rb` should be enough. There is no need to update config.ru as well.

Reference: rack-cors

halfer
  • 19,824
  • 17
  • 99
  • 186
Promise Preston
  • 24,334
  • 12
  • 145
  • 143
2

I had to create a special route to handle the options requests, the cors gem didn't do it for me like I expected it to. The route I added to the end of routes.rb was:

  match "*path", :to => proc {|env| [200, {
  'Access-Control-Allow-Origin' => '*',
  'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Credentials' => 'true',
  'Access-Control-Request-Method' => '*',
  'Access-Control-Allow-Headers' => 'Origin, X-Requested-With, Content-Type, Accept, Authorization',
'Content-Type' => 'text/plain'

 }, ["CORS Preflight"]] }, :via => [:options]
TomDunning
  • 4,829
  • 1
  • 26
  • 33
0

After all it came out that this gem has some issues with heroku, on the local machine it works perfectly fine.

Prostakov
  • 910
  • 1
  • 12
  • 22
-2

Make sure you added or uncommented gem 'rack-cors' in the Gemfile

andreofthecape
  • 1,166
  • 11
  • 24