2013-07-25 34 views
77

如何禁用cors?出于某种原因,我通配符的允许的起源和头但我的Ajax请求仍然抱怨说,出身不是由我CORS政策允许....通过CORS策略允许任何内容

我的应用程序控制器:

class ApplicationController < ActionController::Base 
    protect_from_forgery 
    before_filter :current_user, :cors_preflight_check 
    after_filter :cors_set_access_control_headers 

# For all responses in this controller, return the CORS 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 

# If this is a preflight OPTIONS request, then short-circuit the 
# request, return only the necessary headers and return an empty 
# text/plain. 

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 
    private 
    # get the user currently logged in 
    def current_user 
    @current_user ||= User.find(session[:user_id]) if session[:user_id] 
    end 
    helper_method :current_user 

end 

路线:

match "*all" => "application#cors_preflight_check", :constraints => { :method => "OPTIONS" } 
    match "/alert" => "alerts#create" 
    match "/alerts" => "alerts#get" 
    match "/login" => "sessions#create" 
    match "/logout" => "sessions#destroy" 
    match "/register" => "users#create" 

编辑---

我也试过:

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

在application.rb中

--edit 2 ---

的问题是,Chrome浏览器扩展可能不支持CORS我想。我如何获取绕过CORS的信息?我应该如何回复预检检查?

+1

不是“禁止CORS”但有效的没有政策?我似乎无法回应任何请求。 – Nonconformist

+1

你在localhost上使用这个吗? – nXqd

回答

127

我对您使用rails-api的公共API有相同的要求。

我也在过滤器中设置标题。它看起来像这样:

headers['Access-Control-Allow-Origin'] = '*' 
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS' 
headers['Access-Control-Request-Method'] = '*' 
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization' 

看起来你错过了访问控制请求方法头。

+0

哇,这是一个简单的错误。 谢谢。 – Nonconformist

+0

奇怪。这是工作,而不是停止再次工作.... – Nonconformist

+0

这很奇怪。你能提供关于你得到的错误的更多信息吗? – matteo

18

看看rack-cors中间件。它将以可配置的方式处理CORS头文件。

+1

我也试过 – Nonconformist

+2

我们已经使用了机架数月,至今没有遇到任何问题。你确定问题不在客户端? – Jef

+1

我认为问题在于Chrome扩展不支持CORS,因此Origin可能为空。我如何完全禁用CORS并响应任何请求,包括具有空来源的请求? – Nonconformist

3

我曾经遇到过类似的问题,事实证明,这是网络浏览器(在我的情况是铬),这是问题。

如果您使用的是Chrome,尝试启动它这样:

对于Windows:

1)创建一个快捷方式到Chrome浏览器在桌面上。右键单击该快捷方式并选择属性,然后切换到“快捷方式”选项卡。

2)在“目标”字段,追加以下:-args -disable-web的安全

对于Mac,打开一个终端窗口,并从命令行运行此: 开〜/应用/谷歌\ Chrome.app/ -args - 禁用 - 网络安全

以上信息来自:

http://documentumcookbook.wordpress.com/2012/03/13/disable-cross-domain-javascript-security-in-chrome-for-development/

+0

这是为什么被拒绝?我遇到了类似于问题中描述的情况,该问题通过在禁用Web安全性的情况下运行chrome来解决。当您在本地运行开发服务器时会发生此问题。显然你不会离开铬运行,并始终禁用网络安全。 – klavado

+0

这不应该被拒绝,因为他正确地解释了这种情况:) – nXqd

+3

我没有做下投票,但是从答案来看,这仅仅是一个解决方案,仅仅用于开发目的。虽然这可能会在本地解决问题,但不能指望您的网络访问者/分机用户这样做。所以我会在答案中澄清。 – nathanvda

3

我有问题,特别是与Chrome的为好。你做的看起来基本上和我在应用程序中做的一样。唯一的区别是我在Origin CORS头文件中使用了正确的主机名,而不是通配符。在我看来,Chrome对此很挑剔。

在开发和生产之间切换是一个痛苦,所以我写了这个小函数,它帮助我在开发模式和生产模式下工作。除非另有说明,以下所有情况都发生在我的application_controller.rb中,可能不是最佳解决方案,但rack-cors对我也不起作用,我不记得原因。

def add_cors_headers 
    origin = request.headers["Origin"] 
    unless (not origin.nil?) and (origin == "http://localhost" or origin.starts_with? "http://localhost:") 
    origin = "https://your.production-site.org" 
    end 
    headers['Access-Control-Allow-Origin'] = origin 
    headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS, PUT, DELETE' 
    allow_headers = request.headers["Access-Control-Request-Headers"] 
    if allow_headers.nil? 
    #shouldn't happen, but better be safe 
    allow_headers = 'Origin, Authorization, Accept, Content-Type' 
    end 
    headers['Access-Control-Allow-Headers'] = allow_headers 
    headers['Access-Control-Allow-Credentials'] = 'true' 
    headers['Access-Control-Max-Age'] = '1728000' 
end 

然后,我有我的application_controller.rb这个小东西,因为我的网站需要登录:

before_filter :add_cors_headers 
before_filter {authenticate_user! unless request.method == "OPTIONS"} 

在我routes.rb我也有这样的事情:

match '*path', :controller => 'application', :action => 'empty', :constraints => {:method => "OPTIONS"} 

这种方法看起来像这样:

def empty 
    render :nothing => true 
end 
+1

只是为了关闭这个圈子。这整个CORS混乱只发生在你从本地主机应用程序击中你的制作后端时,对吧? 当所有东西都在生产时,这些都不会发生吗? – Sebastialonso

+2

仅当后端和webapp托管在同一个URL下时。如果它们完全托管在两个不同的URL中,那么这也将在生产中发生。 –

+0

谢谢克里斯托弗。 – Sebastialonso

-4

这其中也支持大多数PHP框架

Header set Access-Control-Allow-Methods "GET, POST, OPTIONS" 
Header set Access-Control-Allow-Origin "*" 
Header set Access-Control-Allow-Credentials true 
Header set Access-Control-Allow-Headers "accept, content-type, X-Requested-With, X-Prototype-Version, X-CSRF-Token, authorization" 

只要确保你对此有何评论?原线在httpd.conf文件

# Virtual hosts 
#Header always set Access-Control-Allow-Origin "*" 
Include /private/etc/apache2/extra/httpd-vhosts.conf 

或者你将结束与多个起源“ *,*“问题

-3

尝试在/config/application.rb配置:

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

你忘了提及dev应该在Gemfile中加上'rack-cors' –

3

只要你可以添加机架CORS宝石 https://rubygems.org/gems/rack-cors/versions/0.4.0

第1步: 添加宝石到你的Gemfile:

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

,然后保存并运行bundle install

第二步: 更新您的config/application.rb文件加入以下内容:

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

更多的细节,你可以去https://github.com/cyu/rack-cors Specailly如果你不使用导轨5.

+0

这个肯定解决了我的问题。谢啦 –