19

我正在尝试将 Rack::Cors 与我的 Rails 4 应用程序一起使用,以便我可以执行基于 JSON 的 API。

CORS 在我的 Gemfile 中是这样的:

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

我确实找到了这个问题(Can't get rack-cors working in rails application),但没有提供任何有用的答案。

更新 2013 年 11 月 13 日 16:40 EST

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

通过我的猴子补丁,我在、和方法中放置puts了语句。和方法都被调用。该方法永远不会被调用。因此,似乎有一些东西在请求到达 cors 中间件之前停止了请求。initializecallallowinitializeallowcall

4

6 回答 6

15

我遇到了与heroku相同的问题。我发现这个博客有同样的 rack-cors 问题。

刚刚移动use Rack::Corsconfig.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
于 2013-12-09T07:22:15.700 回答
4

看起来问题是由我的机器或我所在的网络引起的。我通过 SSH 连接到我使用的托管环境,并使用了上面的 curl 命令,它工作正常。

附加说明 这是刚刚发生的其他事情,我认为我应该补充一下。我的 AJAX 请求不是针对我的 Heroku 应用程序的 https URL,而是 Heroku 将其翻译为 https。这导致了一个额外的跨域问题。切换到对 AJAX 请求使用 https 解决了这个问题。

于 2013-12-09T19:14:18.780 回答
2

好的,感谢 Jason,我能够为我找出根本原因。我安装了 Cisco AnyConnect VPN 客户端,它阻止了 CORS 请求。

您可以在此处了解更多信息: http ://www.bennadel.com/blog/2559-Cisco-AnyConnect-VPN-Client-May-Block-CORS-AJAX-OPTIONS-Requests.htm

突然卸载它可以让一切正常工作!

于 2013-12-09T23:36:04.457 回答
1

我遇到了类似的问题,我无法从 angularjs 的响应中读取 Location 标头,即使我可以在 chrome 的开发工具中看到它。我有这样的 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
于 2014-11-09T11:34:00.357 回答
0

尝试

config.middleware.insert_before ActionDispatch::Static, Rack::Cors do
  # ...
end
于 2013-12-05T18:38:28.130 回答
0

如果您使用的是 Rails 6:

首先转到您的Gemfile并取消注释gem 'rack-cors'。然后运行bundle install

之后转到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 '*'然后相应地设置它。

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

于 2020-10-12T12:07:48.337 回答