CORS not working on Rails 6 with React frontend on different ports

Viewed 1087

running rails 6.1.1 development server on http://localhost:3000 (via rails s)
react client on http://localhost:3001 (via yarn start)

I have tried the following

in gemfile, gem 'rack-cors' and bundle install

in config/intializers/cors.rb

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end

in application.rb

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

example axios request from react js client

axios.post('http://localhost:3000/users', {user}, {withCredentials: true})
      .then(response => {
    ...
     })
      .catch(error => console.log('api errors:', error))
    };

also tried replacing localhost with 127.0.0.1, prepending http:// in config, but none of the solutions are working

response error says blocked by CORS policy

Access to XMLHttpRequest at 'http://localhost:3000/users' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

enter image description here

1 Answers

If you've config/initializers/cors.rb already set up, there's no need to add configurations in application.rb

Had the same issue and my setup for cors.rb looks like:

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

But, this is how I create axios request(please note the headers part):

let service = axios.create({
  headers: {
    'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': '*' <=== notice this header here
  },
  baseURL: process.env.VUE_APP_API_PATH
});
service.interceptors.response.use(this.handleSuccess, this.handleError);
this.service = service;

And use it like:

this.service.request({
      method: 'POST',
      url: path,
      responseType: 'json',
      data: payload
    }).then((response) => {
      return { status: response.status, data: response.data };
    });
Related