Rails在CORS预检选项请求中响应404

Rol*_*dus 44 xmlhttprequest rails-routing http-method cors ruby-on-rails-4

我正在使用Rails 4创建一组服务,我正在使用JavaScript浏览器应用程序.跨源GETS工作正常,但我的POST未通过预检OPTIONS检查404错误.至少,我认为这是正在发生的事情.以下是控制台中出现的错误.这是Mac上的Chrome 31.0.1650.63.

OPTIONS http://localhost:3000/confessor_requests 404 (Not Found) jquery-1.10.2.js:8706
OPTIONS http://localhost:3000/confessor_requests No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. jquery-1.10.2.js:8706
XMLHttpRequest cannot load http://localhost:3000/confessor_requests. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. main.html:1
Run Code Online (Sandbox Code Playgroud)

我已经搜索了关于启用CORS的指令的高低,我很难过.通常的建议似乎是将这样的东西放在Application控制器中,我做了.

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, PUT, 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, PUT, GET, OPTIONS'
    headers['Access-Control-Allow-Headers'] = '*'
    headers['Access-Control-Max-Age'] = '1728000'
    render :text => '', :content_type => 'text/plain'
  end
end
Run Code Online (Sandbox Code Playgroud)

在routes.rb中的某种路由后面会在OPTIONS请求进入时重定向到此操作.

match "/*all" => "application#cors_preflight_check", :constraints => { :method => "OPTIONS" }
Run Code Online (Sandbox Code Playgroud)

'match'指令不再适用于Rails 4,所以我摆弄它,试图让它直接匹配POSTS,如下所示:

post "/*all" => "application#cors_preflight_check", :constraints => { :method => :options }
Run Code Online (Sandbox Code Playgroud)

但它仍然无效.由于GET请求正在运行,我假设我缺少的是OPTIONS请求的正确路由.但是,我已经尝试了我能想到的每一条路线,似乎没有任何东西让请求通过.

我也尝试过安装cyu/rack-cors,这也给出了相同的结果.

谁知道我做错了什么?

Tyl*_*ier 24

这是一个使用rack-cors gem的解决方案,你说你试过了.正如其他人所提到的那样,您没有详细说明您正在使用哪个前端框架以及实际请求是什么样的.所以以下内容可能不适用于您,但我希望它对某人有所帮助.

在我的情况下,宝石工作正常,直到我使用PUT(或PATCH或DELETE).

如果您查看浏览器开发人员控制台,请查看请求标头,您应该有这样一行:

Access-Control-Request-Method: PUT
Run Code Online (Sandbox Code Playgroud)

需要注意的重要一点是,methods您传递给的resource是,而Access-Control-Request-Method不是在飞行前检查后要求的请求方法.

请注意我:methods => [:get, :post, :options, :delete, :put, :patch]将如何包含我关心的所有方法.

因此,您的整个配置部分应如下所示development.rb:

# This handles cross-origin resource sharing.
# See: https://github.com/cyu/rack-cors
config.middleware.insert_before 0, "Rack::Cors" do
  allow do
    # In development, we don't care about the origin.
    origins '*'
    # Reminder: On the following line, the 'methods' refer to the 'Access-
    # Control-Request-Method', not the normal Request Method.
    resource '*', :headers => :any, :methods => [:get, :post, :options, :delete, :put, :patch], credentials: true
  end
end
Run Code Online (Sandbox Code Playgroud)


anc*_*jic 11

使用Rails 3.2.11.

我放

match '*path', :controller => 'application', :action => 'handle_options_request', :constraints => {:method => 'OPTIONS'}
Run Code Online (Sandbox Code Playgroud)

在我的routes.rb文件中.关键是把它作为最高优先级(在routes.rb文件之上).创建该操作以使其公开可用:

  def handle_options_request
    head(:ok) if request.request_method == "OPTIONS"
  end
Run Code Online (Sandbox Code Playgroud)

应用程序控制器中的过滤器:

 after_filter :set_access_control_headers

  def set_access_control_headers
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
  end
Run Code Online (Sandbox Code Playgroud)

  • 这个答案适用于Rails 3,但问题是关于Rails 4. (5认同)

Nic*_*gen 6

是的,正如其他人指出的那样,创业板可能会做得更好.但是因为我非常喜欢原始博客文章中用cors代码指出的方法,所以如果您使用该代码,我已经找到了Rails 4解决方案.

在您的routes.rb中:

match '*all' => 'my_method_name#cor', via: :options
Run Code Online (Sandbox Code Playgroud)

在my_method_name控制器中:

def cor
    # blank section for CORR
    render :text => ''
end
Run Code Online (Sandbox Code Playgroud)

只要你有这个加上你的其他代码:

before_filter :cors_preflight_check
after_filter :cors_set_access_control_headers
...
Run Code Online (Sandbox Code Playgroud)

然后你应该为Rails 4设置.