Rack-cors 在 swagger-ui_rails 的生产环境中未显示 headers

Rack-cors not showing headers in production env for swagger-ui_rails

我目前 运行 几个 Rails 3.2.x 应用程序。使用 Ruby 1.9.x 并且是 api 端点的那个端点上有 Rack-cors gem (1.0.1) - app Alice;另一个运行 swagger-ui_rails gem 并且是托管 api 文档的应用程序 -- 应用程序 Bob。 swagger 文档是使用 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 信息。但是响应 headers 肯定没有所需的 Access-Control-Allow-Origin header.

这通过 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 的网络选项卡中,这是我本地的(dev/localhost 中的 Bob 和 Alice)

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 那样 return 任何类型的 header,即使使用完全相同的 Rack-Cors代码块。

rake middleware 在堆栈顶部显示 Rack::Cors,而 curl -i https://alice.example.com/api-docs/v1/api-docs.json 从未 return 编辑过正确的 access-control header对我来说,在本地和 Bob 的服务器上。

prod-Bob 也有一些 EBS 扩展,用于向 nginx 添加一些请求 headers 和方法。在其他一些 SO post 中,我看到人们直接通过 Rails 添加响应 header,因此 Bob 在 application_controller.rb 中也有以下内容(在开发中,使用 binding.pry, 我可以确认响应肯定有指定的 headers)

  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

我有点不知所措,如有任何帮助或想法,我们将不胜感激。

我正在使用的 Swagger-docs gem 将我创建的 .json 文件放入 Rails' /public 目录。因此,Rails 将其视为静态文件,而不是应该通过 Rack 中间件的文件。由于我们的 production.rb 文件有 config.serve_static_assets = false,这意味着所有这些静态文件都是我们的网络服务器 (Apache/Nginx) 的责任,而不是 rack-cors [=32= 的责任].

在将一些 CORS headers 添加到 Apache 后,swagger-ui 正确加载,但加倍了 headers - 第一个用于 Apache,第二个用于 rack-cors。

我已删除 rack-cors gem 并根据与通配符子域相关的 SO 答案调整了 Alice 上的 Apache 服务器 conf 设置:

/etc/apache2/sites-enabled/mysite.conf

SetEnvIf Origin ^(https?://.+\.example\.com(?::\d{1,5})?)$   CORS_ALLOW_ORIGIN=
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"