Heroku、Rails 4和Rack::Cors

Heroku、Rails 4和Rack::Cors,heroku,ruby-on-rails-4,cors,Heroku,Ruby On Rails 4,Cors,我正在尝试在Rails 4应用程序中使用Rack::Cors,以便能够实现基于JSON的API CORS在我的GEM文件中如下所示: gem 'rack-cors', :require => 'rack/cors' config.middleware.insert_after Rails::Rack::Logger, Rack::Cors, :debug => true, :logger => Rails.logger do allow do orig

我正在尝试在Rails 4应用程序中使用Rack::Cors,以便能够实现基于JSON的API

CORS在我的GEM文件中如下所示:

gem 'rack-cors', :require => 'rack/cors'
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
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
我在application.rb文件中进行如下配置:

gem 'rack-cors', :require => 'rack/cors'
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
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
我在
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
我确实发现了这个问题(),但没有提供任何有用的答案

更新日期2013年11月13日美国东部时间16:40

我一直在尝试对正在发生的事情进行更多的调试。我已经对Rack::Cors的一些方法进行了monkey补丁,看看它们是否在Heroku上被调用。我还更改了插入COR的位置,使其位于机架中间件堆栈的顶部

在我的猴子补丁中,我在
初始化
调用
允许
方法中放置了
放置
语句。
initialize
allow
方法都被调用。从不调用
调用
方法。因此,似乎有什么东西在请求到达cors中间件之前阻止了它。

试试看

config.middleware.insert_before ActionDispatch::Static, Rack::Cors do
  # ...
end

我和heroku遇到了同样的问题。我发现了同样的机架cors问题

刚刚将
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

问题似乎是由我的机器或我所在的网络引起的。我进入了一个我使用的托管环境,并使用了上面的curl命令,它成功了

附加说明
这里还有一些刚刚发生的事情,我想我应该补充一下。我的AJAX请求不是针对我的Heroku应用程序的https URL,但Heroku正在将其转换为https。这导致了另一个跨来源问题。在AJAX请求中切换到使用https解决了这个问题。

好的,多亏了Jason,我才能够找到根本原因。我安装了Cisco AnyConnect VPN客户端,它正在阻止CORS请求

您可以在此处找到更多信息:


突然卸载它,一切正常

我也遇到了类似的问题,我无法从angularjs中的响应中读取位置头,尽管我可以在chrome的开发工具中看到它。我将Rack::Cors设置为:

gem 'rack-cors', :require => 'rack/cors'
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
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

如果您使用的是Rails 6:

首先转到您的
gem文件
并取消注释
gem'rack cors'
。然后运行
bundle安装

然后进入
config/initializers
文件夹。在那里,您应该可以找到一个名为
cors.rb
的文件

取消注释如下所示的代码

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'example.com'

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end
将显示
origins'example.com'
的行更改为
origin'*'
,或者如果您的请求将来自特定的源,则相应地进行设置


这对我有用。希望它对你也有用。干杯

你有想过吗?我一直在间歇性地工作。。。。但根本不知道如何在heroku上调试它:(@Mark37我还没弄明白。我发誓我昨天才让它工作。有趣的是,heroku日志甚至没有注册我的选项请求,所以我提交了一张支持票,看看heroku路由器是否有问题。如果我听到任何消息,我会发回。还有一个奇怪的事实,如果我的服务因为空闲而停止,我试图发出curl选项请求,dyno不会再次启动。只有当我发出GET、POST、PUT、DELETE时,dyno才会开始旋转。我可以确认这对我来说也是如此-但我真的想知道为什么这使得我无法从这个特定的网络使用我的webapp。这完全是我们的问题!没有VPN很好&那些有问题的。我们的默认系统映像安装了它,所以我们也不得不手动删除它。非常感谢,Mark37:-)