CORS не работает на Rails 6 с интерфейсом React на разных портах

#ruby-on-rails #reactjs #axios #cors #ruby-on-rails-6

#ruby-на-рельсах #reactjs #аксиос #корс #ruby-on-rails-6

Вопрос:

запуск rails 6.1.1 сервер разработки на http://localhost:3000 (через rails s )
клиент react на http://localhost:3001 (через yarn start )

Я попробовал следующее

в gemfile gem 'rack-cors' и установите пакет

в 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
 

в application.rb

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

пример запроса axios от клиента react js

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

 

также пробовал заменить localhost на 127.0.0.1 , http:// добавив в config, но ни одно из решений не работает

сообщение об ошибке ответа заблокировано политикой CORS

 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.
 

введите описание изображения здесь

Ответ №1:

Если вы config/initializers/cors.rb уже все настроили, нет необходимости добавлять конфигурации в application.rb

Была такая же проблема, и моя настройка cors.rb выглядит так:

 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

 

Но именно так я создаю запрос axios (пожалуйста, обратите внимание на часть заголовков):

 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;
 

И используйте его как:

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