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