Разрешить CORS в Ruby on Rails
в своем config/application.rb
файл, у меня есть этот код,
config.action_dispatch.default_headers = {
'Access-Control-Allow-Origin' => '*',
'Access-Control-Request-Method' => 'GET, PATCH, PUT, POST, OPTIONS, DELETE'
}
но это не позволяет мне отправить почтовый запрос на маршрут по моему северу
Safari дает эту ошибку:
http://localhost:3000/studentsFailed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:3000/studentsFailed to load resource: Origin http://localhost:4200 is not allowed by Access-Control-Allow-Origin.
localhost:1XMLHttpRequest cannot load http://localhost:3000/students. Origin http://localhost:4200 is not allowed by Access-Control-Allow-Origi
и в моей консоли сервера Rails:
Started OPTIONS "/students" for ::1 at 2015-03-28 21:00:45 -0500
ActionController::RoutingError (No route matches [OPTIONS] "/students"):
5 ответов
Я потратил некоторое время, работая над этим, и я могу сказать вам, что самое надежное решение-использовать стойки. смотри:https://github.com/cyu/rack-cors
Сначала добавьте драгоценный камень:
gem 'rack-cors', '~> 0.3.1'
потом в приложение.rb add
config.middleware.insert_before 0, "Rack::Cors" do
allow do
origins '*'
resource '*', :headers => :any, :methods => [:get, :post, :options]
end
end
я смог понять это с небольшой помощью из ответа @Akiomi:
в своем routes.rb
, я добавил следующий код в верхней части файла:
match '(:anything)' => 'application#nothing', via: [:options]
далее, в моем контроллере приложений, я добавил:
def nothing
render text: '', content_type: 'text/plain'
end
вместе с заголовками в config/application.rb
:
config.action_dispatch.default_headers = {
'Access-Control-Allow-Origin' => '*',
'Access-Control-Request-Method' => 'GET, PATCH, PUT, POST, OPTIONS, DELETE',
'Access-Control-Allow-Headers:' => 'Origin, X-Requested-With, Content-Type, Accept'
}
да, обратите внимание на 'Access-Control-Allow-Headers:' => 'Origin, X-Requested-With, Content-Type, Accept'
это не было включено в мой первоначальный вопрос, это одна из больших проблем.
добавить следующий код:
на config/routes.rb
:
match 'students' => 'students#option', via: [:options]
на controllers/student_controller.rb
:
def option
render text: '', content_type: 'text/plain'
end
или вы можете использовать rack-cors.
в некоторых случаях браузер будет выполнять предпусковой запрос: вместо того, чтобы фактически выполнять запрос, он сначала выполняет запрос опций на тот же url-адрес, чтобы он мог узнать, каковы значения различных заголовков CORS (подробнее о предварительной подсветке здесь). Если этот запрос успешен и заголовки имеют правильные значения, он выполняет фактический запрос.
вы не добавили маршрут для этих запросов опций, поэтому они переходят на страницу rails 404, которая не включает заголовки CORS.
ответ OPTIONS просто должен установить те же заголовки CORS, которые вы обычно устанавливаете во время запроса. Он не должен делать ничего другого. Например
match 'students' => 'students#cors_preflight', via: [:options]
def cors_preflight
render nothing: true
end
обратите внимание, что есть другие заголовки CORS, которые вам может потребоваться установить, например Access-Control-Allow-Credentials
, Access-Control-Allow-Headers
когда у вас есть эта работа, вы можете рассмотреть вопрос о том, чтобы немного затянуть это - вы потенциально открываете свое приложение для межсайтовых атак сценариев.
вы можете разрешить происхождение из application_controller
class ApplicationController < ActionController::Base
before_action :allow_cross_domain_ajax
def allow_cross_domain_ajax
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Request-Method'] = 'POST, OPTIONS'
end
end