I cannot get Access-Control-Allow-Origin
to show up in Chrome - my ultimate goal is to configure CORS for fonts with Rails, so it works in production
with CloudFront. For now though, I just want to get it to work in development
. I can see the header via curl
, but not Chrome.
I am using Rails 4.0
, and I have tried all of the following...
I have configured Gemfile
and application.rb
as per the rack-cors example for rails 4:
Gemfile
gem 'rack-cors', '~> 0.2.9', require: 'rack/cors'
config/application.rb
config.middleware.insert_before 'ActionDispatch::Static', 'Rack::Cors' do
allow do
origins '*'
resource '*',
:headers => :any,
:methods => [:get, :options, :head]
end
end
rails console
2.0.0-p481 :001 > Rails.env
=> "development"
2.0.0-p481 :002 > Hello::Application.config.serve_static_assets
=> true
bash
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
Chrome (v37) Developer Tools > Network > OpenSans-Regular-webfont.woff > Headers > Response Headers
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
I also tried the following alternatives, as per various sources:
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
I also tried the following to applications.rb
, as per How to Display FontAwesome in Firefox Using Rails and CloudFront:
config.assets.header_rules = {
:global => {'Cache-Control' => 'public, max-age=31536000'},
:fonts => {'Access-Control-Allow-Origin' => '*'}
}
I also tried the following in config.ru
, as per CloudFront CDN with Rails on Heroku
require 'rack/cors'
use Rack::Cors do
allow do
origins '*'
resource '*', :headers => :any, :methods => :get
end
end
bundle exec rake middleware
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
I also tried font_assets to no avail.
YES! Finally.
user664833's answer above is great, except I couldn't find my Passenger config file to edit.
Thomas Nye's answer here gives the full file to create at config/nginx.conf.erb:
Procfile
should include the line:web: bundle exec passenger start -p $PORT --max-pool-size 3 --nginx-config-template config/nginx.conf.erb
You'll also need to configure you Cloudfront CDN that is serving the assets as per Guapolo's answer
In your distribution that is giving you the CORS grief, go to the behaviours tab, and a new behaviour, selecting the path to the asset, i.e. /assets/icons.ttf and whitelist 'Origin' as per the above image.
You may also need, in you distribution, to 'invalidate' the old cached resource, in the invalidations tab, i.e. put in the full asset and cached name from your inspector, and invalidate. Once that has processed, deploy the app with the config and restart heroku. You'll need to open inspector and 'empty cache and hard reload' the page.
Hopefully that works - it sounds like the passenger config changes every now and then, so we may find this breaks and the answer will need to be updated to reflect the new config.
You might want to try these solutions or a combination:
The
Server
line made me think that perhaps the assets are not being handled by Rails, but rather bynginx
:This means that the headers must be added by
nginx
, not Rails, and therefore we need to configurenginx
. It turns out that the ability to configurenginx
is possible as of Passenger 4.0.39 - (here is the corresponding Git diff). The corresponding documentation is available in Passenger Standalone, under Advanced configuration.An important note in the documentation: The original configuration template file may change from time to time, e.g. because new features are introduced into Phusion Passenger. If your configuration template file does not contain the required changes, then these new features may not work properly. In the worst case, Standalone might even malfunction. Therefore, every time you upgrade Phusion Passenger, you should check whether the original configuration template file has changed, and merge back any changes into your own file.
With respect to that note, in addition to the customizable copy of the configuration file, create an "original" copy that you can
diff
whenever you upgrade Passenger.bash
Next, add
--nginx-config-template config/nginx.conf.erb
to theweb
line inProcfile
.Procfile
config/nginx.conf.erb
Next, edit the configuration file
config/nginx.conf.erb
by finding a block that looks as follows:...and add the two
Access-Control
lines:That's it. This will work in
production
, but not indevelopment
, due toconfig.assets
differences between the two.the config diff
The
diff
should not return anything now, but if any future updates to passenger include a change to this file, you will know.nginx documentation
future improvements
Allow-Origin
Request-Method
I'm not sure that it is answer, but it looks like you also could try the easiest way with using
after_filter
with: