Rails 跨域 ajax 获取请求 (CORS)

Posted

技术标签:

【中文标题】Rails 跨域 ajax 获取请求 (CORS)【英文标题】:Rails cross domain ajax get request (CORS) 【发布时间】:2016-09-12 07:29:01 【问题描述】:

我正在尝试在我的 rails 应用中实现 google places api。

这是我在尝试使用从 ajax 请求中获取数据的函数时遇到的错误:

XMLHttpRequest cannot load . Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

我正在使用 rack-cors gem,并将这个 sn-p 添加到我的 config/application.rb 文件中:

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

这是我认为的 ajax 请求(coffeescript):

    $.ajax
      url: url
      dataType: "json"
      type: "GET"

我已将此部分添加到我的 application_controller

before_filter :cors_preflight_check
after_filter :cors_set_access_control_headers

def cors_set_access_control_headers
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
headers['Access-Control-Allow-Headers'] = '*'
headers['Access-Control-Max-Age'] = "1728000"
end

def cors_preflight_check
if request.method == :options
  headers['Access-Control-Allow-Origin'] = '*'
  headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
  headers['Access-Control-Allow-Headers'] = '*'
  headers['Access-Control-Max-Age'] = '1728000'
  render :text => '', :content_type => 'text/plain'
end
end

这个,到我的路线文件

 match '*path' => 'application#cors_preflight_check', :via => :options

我注意到“cors_preflight_check”方法不是由我的请求触发的。 (当我单击视图中的某个链接时,我会发出 AJAX 请求)

我注意到我的请求标头保持不变。

(Access-Control-Allow-Origin 未添加到请求标头中)

jsonp 不是一个选项,因为places api 不支持它

尝试了这些线程中编写的所有内容:

https://github.com/cyu/rack-cors/issues/33 Can't get rack-cors working in rails application (config.middleware.insert 0, Rack::Cors do) https://demisx.github.io/rails-api/2014/02/18/configure-accept-headers-cors.html POST Method not working in rack-cors rails 4(在应用控制器中添加前后操作) Add custom response header with Rack-cors and Grape(使用 :expose 键)

【问题讨论】:

你要部署什么?这是您的本地开发设置吗?对于我的部署,我最终不得不在我的例子 nginx 的配置文件中设置服务器设置中的标头。 我相信我在使用 Webrick,你能解释一下吗? 【参考方案1】:

我正在尝试在我的 rails 应用中实现 google places api。

您似乎对 CORS 的功能感到困惑。如果您尝试对例如https://maps.googleapis.com 执行ajax 调用,那么唯一重要的是CORS 标头sent in the response by Google。如果这不起作用,您可能正在尝试使用过时的 api 版本端点。

请按照以下步骤操作: https://developers.google.com/maps/documentation/javascript/examples/place-search

如果您希望您的应用程序能够向其他域提供数据,那么您将提供 CORS 标头。但这不太可能是导致您的问题的原因,除非您正在做一个由单独的前端使用的 Rails api 应用程序。

请参阅Using CORS,了解有关 CORS 工作原理的教程。

另一方面,CSP (content security policy) 允许您为跨域请求设置更宽松的规则。但在这种情况下不需要,因为 Google 为其 Web 服务提供了 CORS 标头。

【讨论】:

是否可以在不显示地图的情况下使用这个库?只是以 JSON 格式获取结果?我可能会感到困惑,但这是我按照此处的说明尝试完成的:developers.google.com/places/web-service/search,我做错了吗? 我没有密钥,所以我无法测试端点,但尝试发送请求,例如 Postman 并检查 CORS 标头的响应标头。可能是谷歌尚未为该端点添加它们。 首先谢谢你。我已经让它与 javascript 库一起使用。现在我遇到的问题是在生产中。-现在我需要弄清楚如何添加 SSL 证书,因为 chrome 会阻止地理位置

以上是关于Rails 跨域 ajax 获取请求 (CORS)的主要内容,如果未能解决你的问题,请参考以下文章

CORS跨域请求规则以及在Spring中的实现

ajax跨域之CORS

Ajax-07 基于Ajax实现跨域请求

跨域的另一种解决方案CORS(CrossOrigin Resource Sharing)跨域资源共享

Ajax请求的跨域(CORS)问题

通过 AJAX 进行跨域资源共享 (CORS)