How to enable CORS in Rails 4 App
You should use rack cors
It provides a nice DSL, to use in your config/application.rb
, instead of the messy header work and before filters.
A very permissive would be as follows, but of course, you'll have to tailor it a bit.
use Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: :any
end
end
Rails - Allow localhost in CORS settings only in development
If you're using Rails 5 or older you can handle the configuration when you are injecting the Rack::CORS middleware into the stack:
# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
if Rails.env.development?
origins 'localhost:3000', 'localhost:3001', 'https://my-app.com'
else
origins 'https://my-app.com'
end
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
Since your Rails application is bootstrapped when initializers are loaded you can determine the environment through Rails.env
. If you want to avoid hardcoding you could use an environmental variable.
Allow CORS in Ruby on Rails
I spent some time working on this and I can tell you the most reliable solution is to use rack-cors. see: https://github.com/cyu/rack-cors
First add the gem:
gem 'rack-cors', '~> 0.3.1'
then in application.rb
add
config.middleware.insert_before ActionDispatch::Static, Rack::Cors do
allow do
origins '*'
resource '*', :headers => :any, :methods => [:get, :post, :options]
end
end
If your production app does not serve static assets (such as if you use a serve like nginx or apache), consider replacing ActionDispatch::Static
in the above example with 0
. See https://github.com/cyu/rack-cors#common-gotchas for more information about the argument.
Allow anything through CORS Policy
I've your same requirements on a public API for which I used rails-api.
I've also set header in a before filter. It looks like this:
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
It seems you missed the Access-Control-Request-Method header.
I set up CORS in my Rails app, but I still get the error
In your vue_portfolio/src/components/Articles.vue
you have axios.get('localhost:3000/articles')
, without protocol it is not absolute not relative, browser thinks that you're trying to connect to host 3000
via protocol localhost
and does not allow.
Change it to
axios.get('http://localhost:3000/articles')
or
axios.get('/articles')
(the latter is for same-origin, CORS is not needed in this case)
Heroku, Rails 4, and Rack::Cors
It looks like the issue is being caused by my machine or the network I am on. I SSHed into a hosting environment I use and used the curl command above and it worked.
Additional Note
Here is something else that just happened that I thought I ought to add to this. My AJAX request was not to the https URL for my Heroku app, but Heroku was translating it be https. This was causing an additional cross-origin issue. Switching to use https for the AJAX request fixed this.
Related Topics
How to Reference a Function in Ruby
Sum the Value of Array in Hash
(Ruby) Getting Net::Smtp Working with Gmail...
How to Iterate Activerecord Attributes, Including Attr_Accessor Methods
Changing Table Name at Query Run Time in a Rails Application
How to Invoke an Instance Method on a Ruby Module Without Including It
How to Have Multiple Versions of Ruby and Rails, and Their Combinations on Windows
What's the Difference Between To_A and To_Ary
Install Rails 3 on Osx with Rvm
Ruby Gemspec Dependency: Is Possible Have a Git Branch Dependency
Iterate Over a Deeply Nested Level of Hashes in Ruby
Change the Binding of a Proc in Ruby
Convert Time to Other Timezone
Ruby on Rails Scalability/Performance
How to Merge Two Hashes Without Overwritten Duplicate Keys in Ruby