resource - Heroku, Rails 4 y Rack:: Cors
nginx no access control allow origin header is present on the requested resource (5)
Estoy intentando usar Rack :: Cors con mi aplicación Rails 4 para poder hacer una API basada en JSON.
CORS está en mi Gemfile así:
gem ''rack-cors'', :require => ''rack/cors''
Estoy haciendo la configuración en mi archivo application.rb como este:
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
Estoy insertando después de Rails::Rack::Logger
en un intento de obtener información de depuración.
Estoy usando CURL para probarlo, esto es lo que he estado ejecutando:
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''
Cuando ejecuto la aplicación Rails en mi máquina local, funciona sin problemas. Cuando presiono la aplicación Heroku, esto es lo que obtengo:
> 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
Encontré esta pregunta ( No se puede hacer que rack-cors trabaje en la aplicación Rails ), pero no se proporcionó ninguna respuesta útil.
Actualización 13/11/2013 16:40 EST
He estado intentando depurar un poco más con lo que está pasando. He revisado algunos de los métodos de Rack :: Cors para ver si se los llama a Heroku. También cambié donde inserté Cors para estar en la parte superior de la pila de middleware del rack.
Con mi parche de mono, he puesto declaraciones de puts
en los métodos initialize
, call
y allow
. Los métodos initialize
y allow
son llamados. El método de call
nunca se llama. Entonces parece que hay algo que está deteniendo la solicitud antes de que llegue al middleware de cors.
Tratar
config.middleware.insert_before ActionDispatch::Static, Rack::Cors do
# ...
end
Me encontré con el mismo problema con heroku. Encontré este blog con el mismo problema de rack-cors.
Acabo de mover el use Rack::Cors
a config.ru
, redesplegado a heroku y funciona.
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
Ok, gracias a Jason pude descubrir la causa raíz para mí. Tenía el cliente Cisco AnyConnect VPN instalado y estaba bloqueando las solicitudes CORS.
Puede encontrar más información aquí: http://www.bennadel.com/blog/2559-Cisco-AnyConnect-VPN-Client-May-Block-CORS-AJAX-OPTIONS-Requests.htm
¡Desinstalarlo de repente permitió que todo funcionara!
Parece que el problema está causado por mi máquina o la red en la que estoy. Me SSHed en un entorno de hosting que uso y usé el comando curl anterior y funcionó.
Nota adicional Aquí hay algo más que sucedió que pensé que debería agregar a esto. Mi solicitud AJAX no era para la URL https de mi aplicación Heroku, pero Heroku la traducía como https. Esto estaba causando un problema adicional de origen cruzado. Cambiar a usar https para la solicitud AJAX solucionó esto.
Estaba teniendo un problema similar, no podía leer el encabezado Location desde la respuesta en angularjs, aunque podía verlo en las herramientas de desarrollo de Chrome. Tenía el Rack :: Cors configurado así:
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
La solución para mí fue agregar la ubicación a la opción: exponer, y después de eso pude verla en 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