Navigate back to the homepage

Handling CORS in Rails for client side apps

Amit Solanki
January 20th, 2019 · 1 min read

Building a client side app with React is a bliss, just like building backend with Ruby on Rails. In React if you make an api to call to backend you would get an error like so.

1Response to preflight request doesn’t pass access control check: No \
2‘Access-Control-Allow-Origin’ header is present on the requested resource. \
3Origin ‘http://localhost:4000' is therefore not allowed access. The response had \
4HTTP status code 404. If an opaque response serves your needs, set the request’s \
5mode to ‘no-cors’ to fetch the resource with CORS disabled.

CORS or Cross Origin Resource Sharing gives web server cross domain access control, which enables secure cross-domain data transfers. Browsers use CORS in an API container, such as XMLHttpRequest (what Axios and Fetch use under the hood), to mitigate the risks of cross-origin HTTP requests.

To fix this, we have 2 options.

  1. Set request mode to ‘no-cors’ to fetch the resource with CORS disabled, this will return an opaque response.
  2. Add an ‘Access-Control-Allow-Origin’ header to rails server.

If we set ‘no-cors’ it returns the following Opaque response.

1Response {
2 body: null
3 bodyUsed: false
4 headers: Headers
5 ok: false
6 redirected: false
7 status: 0
8 statusText: ""
9 type: "opaque"
10 url: ""
11}

There are a couple of things to note:

  • the status is “0” (and not a regular HTTP status code - like 200)
  • the statusText is empty
  • the headers object is also empty Basically, we can’t see anything in this Response object - and henceforth the name opaque. Opaque response or ‘no-cors’ mode can be used with <script>, <img>, <video>, <audio>, <link rel="stylesheet">, <object>, <embed> and <iframe> elements.

So it’s of no use to us, given that we need the data from our rails api. We need to add the Access-Control-Allow-Origin header to the rails server. We can use this wonderful gem rack-cors. We need to add the gem to our Gemfile.

1gem 'rack-cors'

And add the following config in config/application.rb file

1module YourApp
2 class Application < Rails::Application
3 # ...
4
5 # Rails 5
6
7 config.middleware.insert_before 0, Rack::Cors do
8 allow do
9 origins '*'
10 resource '*', headers: :any, methods: [:get, :post, :options]
11 end
12 end
13
14 # Rails 3/4
15
16 config.middleware.insert_before 0, "Rack::Cors" do
17 allow do
18 origins '*'
19 resource '*', headers: :any, methods: [:get, :post, :options]
20 end
21 end
22 end
23end

That’s about it, no more CORS issue. 🚀 We are good to go.

More articles from Amit Solanki

How to setup PostgreSQL on MacOS

PostgreSQL setup reference

January 13th, 2019 · 1 min read

10 Console tricks, to debug like a Pro.

Some built-in console methods, which can make debugging fun ;)

October 13th, 2018 · 2 min read
© 2018–2019 Amit Solanki
Link to $https://twitter.com/iamsolankiamitLink to $https://github.com/iamsolankiamit