如何使用rails,nginx和passenger配置`Access-Control-Allow-Origin`?

use*_*833 13 ruby-on-rails passenger nginx http-headers cors

我无法Access-Control-Allow-Origin在Chrome中显示 - 我的最终目标是使用Rails为字体配置CORS,因此它适用于productionCloudFront.但就目前而言,我只是想让它发挥作用development.我可以看到标题通过curl,但不是Chrome.

我正在使用Rails 4.0,我已经尝试了以下所有......

我已经配置Gemfileapplication.rb根据rails 4的rack-cors示例:

的Gemfile

gem 'rack-cors', '~> 0.2.9', require: 'rack/cors'
Run Code Online (Sandbox Code Playgroud)

配置/ application.rb中

config.middleware.insert_before 'ActionDispatch::Static', 'Rack::Cors' do
    allow do
        origins '*'
        resource '*',
            :headers => :any,
            :methods => [:get, :options, :head]
    end
end
Run Code Online (Sandbox Code Playgroud)

rails console

2.0.0-p481 :001 > Rails.env
 => "development"
2.0.0-p481 :002 > Hello::Application.config.serve_static_assets
 => true
Run Code Online (Sandbox Code Playgroud)

庆典

curl -i http://localhost:5000/assets/OpenSans-Regular-webfont.woff

Content-Type: application/font-woff
Content-Length: 22660
Connection: keep-alive
Status: 200 OK
Cache-Control: public, must-revalidate
Last-Modified: Wed, 30 Apr 2014 23:51:57 GMT
ETag: "467b34801137bd4031e139839ad86370"
X-Request-Id: c4b07b4d-1c43-44ea-9565-dfda66378f98
X-Runtime: 0.046007
X-Powered-By: Phusion Passenger 4.0.50
Date: Sat, 20 Sep 2014 04:39:38 UTC
Server: nginx/1.6.1 + Phusion Passenger 4.0.50

curl -i -H "Origin: http://localhost:5000" http://localhost:5000/assets/OpenSans-Regular-webfont.woff

Content-Type: application/font-woff
Content-Length: 22660
Connection: keep-alive
Status: 200 OK
Cache-Control: public, must-revalidate
Last-Modified: Wed, 30 Apr 2014 23:51:57 GMT
ETag: "467b34801137bd4031e139839ad86370"
Access-Control-Allow-Origin: http://localhost:5000   # adding
Access-Control-Allow-Methods: GET, OPTIONS, HEAD     # -H
Access-Control-Max-Age: 1728000                      # produced
Access-Control-Allow-Credentials: true               # these
Vary: Origin                                         # headers
X-Request-Id: b9666f30-416d-4b5b-946a-bdd432bc191c
X-Runtime: 0.050420
X-Powered-By: Phusion Passenger 4.0.50
Date: Sat, 20 Sep 2014 03:45:30 UTC
Server: nginx/1.6.1 + Phusion Passenger 4.0.50
Run Code Online (Sandbox Code Playgroud)

Chrome(v37)开发人员工具>网络> OpenSans-Regular-webfont.woff>标题>响应标题

HTTP/1.1 304 Not Modified
Connection: keep-alive
Status: 304 Not Modified
Cache-Control: no-cache
X-Request-Id: ac153b8c-e0cb-489d-94dd-90aacc10d715
X-Runtime: 0.116511
X-Powered-By: Phusion Passenger 4.0.50
Date: Sat, 20 Sep 2014 03:41:53 UTC
Server: nginx/1.6.1 + Phusion Passenger 4.0.50
Run Code Online (Sandbox Code Playgroud)

根据各种来源,我还尝试了以下替代方案:

config.middleware.insert_before 'ActionDispatch::Static', 'Rack::Cors' do
config.middleware.insert_after Rails::Rack::Logger, Rack::Cors do
config.middleware.insert_before Warden::Manager, Rack::Cors do
config.middleware.insert 0, Rack::Cors do
config.middleware.use Rack::Cors do
Run Code Online (Sandbox Code Playgroud)

我还尝试了以下内容applications.rb,根据如何在Firefox中使用Rails和CloudFront显示FontAwesome:

config.assets.header_rules = {
  :global => {'Cache-Control' => 'public, max-age=31536000'},
  :fonts  => {'Access-Control-Allow-Origin' => '*'}
}
Run Code Online (Sandbox Code Playgroud)

我还尝试了以下内容config.ru,根据Heroku上的Rails使用CloudFront CDN

require 'rack/cors'
use Rack::Cors do
    allow do
        origins '*'
        resource '*', :headers => :any, :methods => :get 
    end 
end
Run Code Online (Sandbox Code Playgroud)

捆绑exec rake中间件

use Rack::Cors
use Rack::Sendfile
use ActionDispatch::Static
use Rack::Lock
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007f9ec21590b0>
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use Warden::Manager
use OmniAuth::Strategies::Facebook
run Hello::Application.routes
Run Code Online (Sandbox Code Playgroud)

我也试过font_assets无济于事.

use*_*833 16

Server条线让我觉得Rails可能没有处理资产,而是通过nginx以下方式处理:

在此输入图像描述

这意味着必须添加标头nginx,而不是Rails,因此我们需要进行配置nginx.事实证明,nginxPassenger 4.0.39开始,配置的能力是可能的 - (这里是相应的Git diff)." 高级配置"下的"乘客独立"中提供了相应的文档.

文档中的一个重要注意事项:原始配置模板文件可能会不时更改,例如因为Phusion Passenger中引入了新功能.如果配置模板文件不包含所需的更改,则这些新功能可能无法正常运行.在最坏的情况下,Standalone甚至可能出现故障.因此,每次升级Phusion Passenger时,都应检查原始配置模板文件是否已更改,并将所有更改合并回您自己的文件中.

关于该注释,除了可配置文件的可自定义副本之外,还可以创建"原始"副本,diff每当升级Passenger时都可以使用该副本.

庆典

cp $(passenger-config about resourcesdir)/templates/standalone/config.erb config/nginx.conf.erb
cp config/nginx.conf.erb config/nginx.conf.erb.original
Run Code Online (Sandbox Code Playgroud)

接下来,添加--nginx-config-template config/nginx.conf.erb到该web行中Procfile.

Procfile

web: bundle exec passenger start -p $PORT --max-pool-size 3 --nginx-config-template config/nginx.conf.erb
Run Code Online (Sandbox Code Playgroud)

配置/ nginx.conf.erb

接下来,config/nginx.conf.erb通过查找如下所示的块来编辑配置文件:

    location @static_asset {
        gzip_static on;
        expires max;
        add_header Cache-Control public;
        add_header ETag "";
    }
Run Code Online (Sandbox Code Playgroud)

...并添加两Access-Control行:

    location @static_asset {
        gzip_static on;
        expires max;
        add_header Cache-Control public;
        add_header ETag "";
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Request-Method *;
    }
Run Code Online (Sandbox Code Playgroud)

而已.由于两者之间的差异production,这将起作用,但不起作用.developmentconfig.assets

配置差异

现在diff不应该返回任何内容,但如果将来对乘客的更新包括对此文件的更改,您将会知道.

diff $(passenger-config about resourcesdir)/templates/standalone/config.erb config/nginx.conf.erb.original
Run Code Online (Sandbox Code Playgroud)

nginx文档

未来的改进

  • 限制 Allow-Origin
  • 限制 Request-Method
  • 将两个标题限制为仅字体