Ruby on rails 允许通过CORS策略执行任何操作
如何禁用cors?出于某种原因,我对允许的来源和标题进行了粗制滥造,但我的ajax请求仍然抱怨我的CORS策略不允许该来源 我的应用程序控制器:Ruby on rails 允许通过CORS策略执行任何操作,ruby-on-rails,cors,Ruby On Rails,Cors,如何禁用cors?出于某种原因,我对允许的来源和标题进行了粗制滥造,但我的ajax请求仍然抱怨我的CORS策略不允许该来源 我的应用程序控制器: class ApplicationController < ActionController::Base protect_from_forgery before_filter :current_user, :cors_preflight_check after_filter :cors_set_access_control_heade
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
编辑---
我还尝试:
config.middleware.use Rack::Cors do
allow do
origins '*'
resource '*',
:headers => :any,
:methods => [:get, :post, :delete, :put, :options]
end
end
in application.rb
--编辑2---
问题是,我认为Chrome扩展可能不支持CORS。如何绕过CORS获取信息?我应该如何响应飞行前检查?看看中间件。它将以可配置的方式处理CORS头。我以前也遇到过类似的问题,问题出在web浏览器(在我的例子中是chrome浏览器)上 如果您正在使用chrome,请尝试启动它,以便: 对于Windows: 1) 在桌面上创建Chrome的快捷方式。右键单击快捷方式并选择“属性”,然后切换到“快捷方式”选项卡 2) 在“目标”字段中,附加以下内容:–args–禁用web安全性 对于Mac,打开一个终端窗口并从命令行运行: 打开~/Applications/Google\Chrome.app/–args–禁用web安全 以上资料来自:
我遇到了一些问题,尤其是Chrome。您所做的基本上与我在应用程序中所做的相似。唯一的区别是,我在原始CORS头中使用正确的主机名进行响应,而不是通配符。在我看来,Chrome对此很挑剔 在开发和生产之间切换是一件痛苦的事情,所以我写了这个小函数,它在开发模式和生产模式中都对我有帮助。以下所有事情都发生在我的
应用程序\u controller.rb中,除非另有说明,否则它可能不是最好的解决方案,但对我也不起作用,我不记得为什么
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
然后我的应用程序\u 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
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'
server {
server_name ...;
listen ...;
root ...;
location / {
add_header 'Access-Control-Allow-Origin' '*';
}
}
我对公共API有相同的要求,我使用了rails API
我还在before过滤器中设置了标题。看起来是这样的:
def empty
render :nothing => true
end
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'
server {
server_name ...;
listen ...;
root ...;
location / {
add_header 'Access-Control-Allow-Origin' '*';
}
}
您似乎错过了访问控制请求方法标题。请尝试在/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
只需添加rack cors gem即可
第一步:
将gem添加到您的gem文件:
gem 'rack-cors', :require => 'rack/cors'
然后保存并运行bundle安装
第二步:
通过添加以下内容更新config/application.rb文件:
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', :headers => :any, :methods => [:get, :post, :options]
end
end
有关更多详细信息,请访问
特别是如果您不使用rails 5。刚刚在我的rails应用程序的生产中遇到这个问题。这里的很多答案给了我一些提示,帮助我最终找到了一个对我来说很好的答案
我正在运行Nginx,只需修改my_app.conf文件(其中my_app是您的应用程序名)就足够简单了。您可以在/etc/nginx/conf.d
如果您还没有location/{}
,您可以将其添加到server{}
下,然后添加add_头“访问控制允许源”*代码>在位置/{}
下
最终格式应如下所示:
def empty
render :nothing => true
end
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'
server {
server_name ...;
listen ...;
root ...;
location / {
add_header 'Access-Control-Allow-Origin' '*';
}
}
使用VSC或任何其他具有Live server的编辑器,它将为您提供一个代理,允许您使用GET或FETCH我们已经使用rack cors几个月了,到目前为止没有遇到任何问题。你确定问题不在客户端吗?我认为问题在于Chrome扩展不支持CORS,所以可能源代码为空。我如何完全禁用CORS并响应任何请求,包括源代码为空的请求?您使用的是什么Chrome扩展?我正在编写一个需要与Rails后端通信的Chrome扩展。为什么会被否决?我遇到了一个类似于问题中描述的情况,通过在禁用web安全的情况下运行chrome解决了这个问题。当您在本地运行开发服务器时,就会出现此问题。显然,你不会让chrome总是在网络安全被禁用的情况下运行。这不应该被否决,因为他正确地解释了这种情况:)我没有否决,但从答案来看,不清楚这仅仅是出于开发目的的解决方案。虽然这可以在本地解决问题,但不能指望web访问者/扩展用户这样做。所以我会在回答中澄清这一点。这里也没有投票,但过去是chrome的第一个实例使用给定的标志运行,导致所有其他实例以相同的方式运行。要非常小心的事情。这太容易忘记和做一些即兴冲浪。不是“禁用CORS”,但实际上没有任何政策?我似乎无法响应任何请求。你在本地主机上使用这个吗?这很奇怪。你能提供更多关于错误的信息吗?如果您不知道将其放置在何处,请检查此项。Access-Control-Request-Method在请求中设置,而不是在响应中设置。只是为了结束这个循环。整个CORS混乱只有在您从本地主机应用程序访问生产后端时才会发生,对吗?当所有内容都在生产中时,这一切都不会发生?只有在后端和webapp托管在同一URL下时才会发生。如果它们完全托管在两个不同的URL下,那么在生产中也会发生这种情况。您忘了提到开发人员应该在gemfile中添加“rack cor”。对于我来说,。在0之前插入_
很重要。在我使用config.middleware.use
之前,这只在我想允许我的public
目录使用CORS之前起作用。