在我的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方式”来处理这个要求?
答案 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