Heroku, Rails 4 и Rack:: Cors
Я пытаюсь использовать Rack:: Cors с моим приложением Rails 4, чтобы я мог использовать API на основе JSON.
В моем Gemfile присутствует CORS:
gem 'rack-cors', :require => 'rack/cors'
Я делаю конфигурацию в файле application.rb следующим образом:
config.middleware.insert_after Rails::Rack::Logger, Rack::Cors, :debug => true, :logger => Rails.logger do
allow do
origins '*'
resource '/messages*', :headers => :any, :methods => [:post, :options]
end
end
Я вставляю после Rails::Rack::Logger
в попытке получить отладочную информацию.
Я использую CURL для его проверки, вот что я использовал:
curl --verbose --request OPTIONS http://jasonbutzinfo.herokuapp.com/messages.json --header 'Origin: http://www.jasonbutz.info' --header 'Access-Control-Request-Headers: Origin, Accept, Content-Type' --header 'Access-Control-Request-Method: POST'
Когда я запускаю приложение rails на своей локальной машине, он работает без проблем. Когда я попал в приложение Heroku, это то, что я получаю:
> OPTIONS /messages.json HTTP/1.1
> User-Agent: curl/7.30.0
> Host: jasonbutzinfo.herokuapp.com
> Accept: */*
> Origin: http://www.jasonbutz.info
> Access-Control-Request-Headers: Origin, Accept, Content-Type
> Access-Control-Request-Method: POST
>
* Empty reply from server
* Connection #0 to host jasonbutzinfo.herokuapp.com left intact
curl: (52) Empty reply from server
Я нашел этот вопрос (Не могу получить стойку, работающую в приложении rails), но не было никакого полезного ответа.
Обновление 11/13/2013 16:40 EST
Я пытаюсь сделать еще несколько отладочных операций с тем, что происходит. У меня есть обезьяна, замаскированная несколькими методами Rack:: Cors, чтобы увидеть, даже если их зовут Heroku. Я также изменил место, где я вставляю Cors в вершину стека промежуточного программного обеспечения.
С моим исправлением обезьяны я поставил puts
заявления в методах initialize
, call
и allow
. Вызываются методы initialize
и allow
. Метод call
никогда не вызывается. Таким образом, кажется, что есть что-то, что останавливает запрос до того, как оно попадет в промежуточное ПО cors.
Ответы
Ответ 1
Похоже, проблема связана с моей машиной или сетью, в которой я включен. я SSHed в среду размещения, которую я использую, и использовал команду curl выше, и она сработала.
Дополнительная заметка
Вот что-то еще, что только что произошло, что я думал, что должен добавить к этому. Мой запрос AJAX был не для URL https для моего приложения Heroku, но Heroku переводил его как https. Это вызвало дополнительную проблему с перекрестным происхождением. Переключение на использование https для запроса AJAX исправило это.
Ответ 2
Я столкнулся с той же проблемой с герокой. Я нашел этот блог с той же проблемой стойки.
Просто переместил use Rack::Cors
в config.ru
, перераспределился в heroku, и он работает.
require ::File.expand_path('../config/environment', __FILE__)
run Rails.application
require 'rack/cors'
use Rack::Cors do
# allow all origins in development
allow do
origins '*'
resource '*',
:headers => :any,
:methods => [:get, :post, :delete, :put, :options]
end
end
Ответ 3
Хорошо благодаря Джейсону, я смог выяснить причину для меня. У меня был установлен клиент Cisco AnyConnect VPN, который блокировал запросы CORS.
Вы можете узнать больше здесь:
http://www.bennadel.com/blog/2559-Cisco-AnyConnect-VPN-Client-May-Block-CORS-AJAX-OPTIONS-Requests.htm
Деинсталляция внезапно позволила всем работать!
Ответ 4
У меня была аналогичная проблема, я не мог прочитать заголовок Location из ответа в angularjs, хотя я мог видеть его в инструментах chrome dev. У меня установлен Rack:: Cors:
config.middleware.insert_before "ActionDispatch::Static", "Rack::Cors" do
allow do
origins '*'
resource '*',
headers: :any,
methods: [:get, :post, :delete, :put, :patch, :options, :head],
max_age: 0
end
end
Решение для меня заключалось в том, чтобы добавить местоположение в параметр: expose, и после этого я мог видеть его в angularjs:
config.middleware.insert_before "ActionDispatch::Static", "Rack::Cors" do
allow do
origins '*'
resource '*',
headers: :any,
methods: [:get, :post, :delete, :put, :patch, :options, :head],
max_age: 0,
expose: :location
end
end
Ответ 5
Попробуйте
config.middleware.insert_before ActionDispatch::Static, Rack::Cors do
# ...
end