单个Rails路由上的Access-Control-Allow-Origin

时间:2016-08-20 15:11:08

标签: ruby-on-rails ruby-on-rails-4 cors

在我的Rails应用程序中,我正在构建一项功能,允许用户使用Javascript代码段从其他网站上嵌入应用程序中的数据。

我的Javascript代码片段向我的rails应用中的路由发出GET请求,该路由返回原始JSON。当代码段和JSON共享同一个域时,一切运行良好,但是当我将代码段嵌入另一个站点时,我遇到了CORS问题。

使用解决方案I found here,我开始为CORS配置我的Rails应用程序。

在我的application_controller.rb

before_filter :add_allow_credentials_headers

def add_allow_credentials_headers
    response.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] || '*'   
    response.headers['Access-Control-Allow-Credentials'] = 'true'
end 

def options
    head :status => 200, :'Access-Control-Allow-Headers' => 'accept, content-type'
end

在我的routes.rb

get 'embed_json' => 'application#options', :via => [:options]

但是,当我在浏览器中点击上述路线时,应用程序不再返回JSON对象 - 只是一个空白屏幕。

在单个Rails路由上如何最好地处理CORS似乎存在许多相互矛盾的方法。有没有“Rails方式”来处理这个要求?

3 个答案:

答案 0 :(得分:2)

head的调用不会返回JSON by definition。使用head调用选项哈希将转换为标头。

可能会尝试这样做,options调用将根据需要提供一个空响应正文的标题。对index的调用应该呈现JSON以及您在add_allow_credentials_headers过滤器中设置的标头。

def add_allow_credentials_headers
  response.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] || '*'   
  response.headers['Access-Control-Allow-Credentials'] = 'true'
  response.headers['Access-Control-Allow-Headers'] = 'accept, content-type'
end 

def options
  head :ok
end

def index
  # do something here that renders a JSON response
end

另外,在你的rails应用程序上启用CORS的另一个选项是rack-cors,可以做你需要的而不用自己做的麻烦。

答案 1 :(得分:1)

status: :ok添加到您要返回的原始JSON中。如果您返回空体,请添加head :ok以返回200状态

要仅为options方法启用CORS,您可以执行以下操作:

before_filter :add_allow_credentials_headers, only: [:options]

def add_allow_credentials_headers
  response.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] || '*' # the domain you're making the request from
  response.headers['Access-Control-Allow-Credentials'] = 'true'
  response.headers['Access-Control-Allow-Headers'] = 'accept, content-type'
end 

def options
  # your json response here or just 'head :ok' if empty 200 response
end

答案 2 :(得分:1)

安装此gem:

gem 'rack-cors', :require => 'rack/cors'

然后将其添加到config / application.rb文件中。

module YourApp
  class Application < Rails::Application

    # ...

    # Rails 3/4

    config.middleware.insert_before 0, "Rack::Cors" do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options]
      end
    end

    # Rails 5

    config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options]
      end
    end

  end
end

这将诀窍阅读更多。 Cors