我目前正在运行几个Rails 3.2.x应用程序。使用Ruby 1.9.x并且是api端点的那个上面有Rack-cors gem(1.0.1) - app Alice;另一个运行swagger-ui_rails gem,是托管api文档的应用程序 - 应用Bob。 swagger docs是用swagger-docs gem创建的,它运行格式版本1.2。出于某种原因,由于这个错误,我无法让应用程序Alice给我Bob的信息:
Failed to load https://alice.example.com/api-docs/v1/api-docs.json:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://bob.example.com:3000' is therefore not allowed access.
然而!当我查看网络选项卡时,响应是200,我可以看到json信息。但响应标头肯定没有所需的Access-Control-Allow-Origin
标头。
通过AWS Elastic Beanstalk(Bob托管在EBS上)和本地(带有绑定地址)都会发生这种情况。
在我的爱丽丝config/environments/production.rb
中,我有以下内容:
config.middleware.insert_before 0, 'Rack::Cors' do
allow do
origins ->(origin, env) do
Rails.logger.warn("CORS origin: #{origin}")
origin =~ /\.example\.com(:\d+)?\z/
end
resource('*', :methods => [:get, :post, :options], :headers => :any)
end
end
当我在Alice的config/environments/development.rb
中有这个代码时,localhost连接并且swagger-ui按预期显示,并且在控制台中没有错误。
在Chrome的网络标签中,这是我本地的(Bob和Alice in dev / localhost)
Access-Control-Allow-Methods:GET, POST, OPTIONS
Access-Control-Allow-Origin:http://apitest.bob.com:3000
Access-Control-Expose-Headers:
Access-Control-Max-Age:1728000
Content-Length:1499
Content-Type:application/json
Date:Fri, 22 Sep 2017 21:44:45 GMT
Last-Modified:Mon, 28 Aug 2017 17:37:22 GMT
Server:
Vary:Origin
这是Bob在开发中并且Alice处于刺激状态时所得到的:
Accept-Ranges:bytes
Connection:keep-alive
Content-Length:1500
Content-Type:application/json
Date:Fri, 22 Sep 2017 23:10:00 GMT
ETag:"abc-559ce64fb8374"
Last-Modified:Fri, 22 Sep 2017 22:04:35 GMT
Server:
正如你所看到的,prod-Alice并没有像dev-Alice那样返回任何类型的头文件,即使使用完全相同的Rack-Cors代码块也是如此。
rake middleware
在堆栈顶部显示Rack :: Cors,curl -i https://alice.example.com/api-docs/v1/api-docs.json
从未在本地和Bob的服务器上为我返回正确的访问控制头。
prod-Bob还有一些EBS扩展,可以为nginx添加一些请求标头和方法。在其他一些SO帖子中,我看到人们通过Rails直接添加响应头,所以Bob在application_controller.rb
中也有以下内容(在dev中,使用binding.pry,我可以确认响应肯定有指定的头)
after_filter :set_access_control_headers
def set_access_control_headers
headers['Access-Control-Allow-Origin'] = Rails.configuration.hostnames['headers']
headers['Access-Control-Request-Methods'] = 'GET, PUT, POST, OPTIONS'
end
我有点不知所措,任何帮助或想法都会受到赞赏。
答案 0 :(得分:1)
我使用的Swagger-docs gem将我创建的.json
文件放入Rails' /public
目录。因此,Rails将其视为静态文件,而不是应该通过Rack中间件的东西。由于我们的production.rb文件有config.serve_static_assets = false
,这意味着所有这些静态文件都是我们的Web服务器(Apache / Nginx)的责任,而不是rack-cors gem的责任。
在向Apache添加一些CORS标头后,swagger-ui被正确加载,但是标头加倍 - 第一个用于Apache,第二个用于机架式连接。
我删除了rack-cors gem并根据与通配符子域相关的SO答案调整了Alice上的Apache服务器配置设置:
<强> /etc/apache2/sites-enabled/mysite.conf 强>
SetEnvIf Origin ^(https?://.+\.example\.com(?::\d{1,5})?)$ CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin %{CORS_ALLOW_ORIGIN}e env=CORS_ALLOW_ORIGIN
Header merge Vary "Origin"
Header set "Access-Control-Allow-Methods" "GET, POST, OPTIONS"