Как настроить "Access-Control-Allow-Origin" с rails, nginx и пассажиром?
я не могу сделать Access-Control-Allow-Origin
чтобы появиться в Chrome-моя конечная цель-настроить CORS для шрифтов с Rails, поэтому он работает в production
С CloudFront. Пока, однако, я просто хочу, чтобы он работал в development
. Я вижу заголовок через curl
, но не Chrome.
я использую Rails 4.0
и я пробовал все следующие...
настройки Gemfile
и application.rb
по состоянию на пример стойки-cors для рельсов 4:
Gemfile
gem 'rack-cors', '~> 0.2.9', require: 'rack/cors'
конфиг/приложения.rb
config.middleware.insert_before 'ActionDispatch::Static', 'Rack::Cors' do
allow do
origins '*'
resource '*',
:headers => :any,
:methods => [:get, :options, :head]
end
end
консоль рельсов
2.0.0-p481 :001 > Rails.env
=> "development"
2.0.0-p481 :002 > Hello::Application.config.serve_static_assets
=> true
Баш
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) инструменты разработчика > сеть > 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
я также попробовал следующие альтернативы, согласно различные источники:
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
я также попробовал следующее applications.rb
на как отобразить FontAwesome в Firefox с помощью Rails и CloudFront:
config.assets.header_rules = {
:global => {'Cache-Control' => 'public, max-age=31536000'},
:fonts => {'Access-Control-Allow-Origin' => '*'}
}
я также попробовал следующий в config.ru
на CloudFront CDN с рельсами на 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
я тоже пробовал font_assets безрезультатно.
4 ответов
на Server
линия заставила меня подумать, что, возможно, активы обрабатываются не рельсами, а скорее nginx
:
это означает, что заголовки должны быть добавлены nginx
, не Rails, и поэтому нам нужно настроить nginx
. Оказывается, что возможность настройки nginx
возможно с пассажира 4.0.39 - (вот соответствующий git diff). Соответствующая документация имеется в пассажирский Автономный, в расширенной конфигурации.
важное примечание в документации: исходный файл шаблона конфигурации может время от времени меняться, например, потому, что новые функции вводятся в Phusion Passenger. Если файл шаблона конфигурации не содержит необходимых изменений, эти новые функции могут работать неправильно. В худшем случае автономный может даже выйти из строя. Поэтому каждый раз при обновлении Phusion Пассажир, вы должны проверить, изменился ли исходный файл шаблона конфигурации, и объединить все изменения в свой собственный файл.
в отношении этой заметки, в дополнение к настраиваемой копии файла конфигурации, создайте "оригинальную" копию, которую вы можете diff
всякий раз, когда вы обновляете пассажира.
Баш
cp $(passenger-config about resourcesdir)/templates/standalone/config.erb config/nginx.conf.erb
cp config/nginx.conf.erb config/nginx.conf.erb.original
далее добавить --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
config / nginx.conf.Эрб
далее отредактируйте файл конфигурации config/nginx.conf.erb
найти блок, который выглядит следующим образом:
location @static_asset {
gzip_static on;
expires max;
add_header Cache-Control public;
add_header ETag "";
}
...и добавьте два 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 *;
}
вот и все. Это будет работать в production
, но не development
, в силу config.assets
различия между двумя.
конфиг diff
на diff
не должен ничего возвращать сейчас, но если какие-либо будущие обновления для passenger включают изменение этого файла, вы узнаете.
diff $(passenger-config about resourcesdir)/templates/standalone/config.erb config/nginx.conf.erb.original
документация nginx
- http://nginx.org/en/docs/beginners_guide.html
- http://nginx.org/en/docs/http/ngx_http_core_module.html#location
будущее улучшения
- ограничения
Allow-Origin
- ограничения
Request-Method
- ограничить оба заголовка только шрифтами
Да! В конечном счете.
user664833 в ответ выше отлично, за исключением того, что я не смог найти файл конфигурации пассажира для редактирования.
ответ Томаса Ная здесь дает полный файл для создания в config / nginx.conf.Эрб:
##########################################################################
# Passenger Standalone is built on the same technology that powers
# Passenger for Nginx, so any configuration option supported by Passenger
# for Nginx can be applied to Passenger Standalone as well. You can do
# this by direct editing the Nginx configuration template that is used by
# Passenger Standalone.
#
# This file is the original template. DO NOT EDIT THIS FILE DIRECTLY.
# Instead, make a copy of this file and pass the `--nginx-config-template`
# parameter to Passenger Standalone.
#
# Learn more about using the Nginx configuration template at:
# https://www.phusionpassenger.com/library/config/standalone/intro.html#nginx-configuration-template
#
# *** NOTE ***
# If you customize the template file, make sure you keep an eye on the
# original template file and merge any changes. New Phusion Passenger
# features may require changes to the template file.
##############################################################
<%= include_passenger_internal_template('global.erb') %>
worker_processes 1;
events {
worker_connections 4096;
}
http {
<%= include_passenger_internal_template('http.erb', 4) %>
### BEGIN your own configuration options ###
# This is a good place to put your own config
# options. Note that your options must not
# conflict with the ones Passenger already sets.
# Learn more at:
# https://www.phusionpassenger.com/library/config/standalone/intro.html#nginx-configuration-template
### END your own configuration options ###
default_type application/octet-stream;
types_hash_max_size 2048;
server_names_hash_bucket_size 64;
client_max_body_size 1024m;
access_log off;
keepalive_timeout 60;
underscores_in_headers on;
gzip on;
gzip_comp_level 3;
gzip_min_length 150;
gzip_proxied any;
gzip_types text/plain text/css text/json text/javascript
application/javascript application/x-javascript application/json
application/rss+xml application/vnd.ms-fontobject application/x-font-ttf
application/xml font/opentype image/svg+xml text/xml;
<% if @app_finder.multi_mode? %>
# Default server entry for mass deployment mode.
server {
<%= include_passenger_internal_template('mass_deployment_default_server.erb', 12) %>
}
<% end %>
<% for app in @apps %>
server {
<%= include_passenger_internal_template('server.erb', 8, true, binding) %>
<%# <%= include_passenger_internal_template('rails_asset_pipeline.erb', 8, false) %1> %>
### BEGIN your own configuration options ###
# This is a good place to put your own config
# options. Note that your options must not
# conflict with the ones Passenger already sets.
# Learn more at:
# https://www.phusionpassenger.com/library/config/standalone/intro.html#nginx-configuration-template
# Rails asset pipeline support.
location ~ "^/assets/.+-([0-9a-f]{32}|[0-9a-f]{64})\..+" {
error_page 490 = @static_asset;
error_page 491 = @dynamic_request;
recursive_error_pages on;
if (-f $request_filename) {
return 490;
}
if (!-f $request_filename) {
return 491;
}
}
location @static_asset {
gzip_static on;
expires max;
add_header Cache-Control public;
add_header ETag "";
if ($http_origin ~* ((https?:\/\/[^\/]*\.herokuapp\.com(:[0-9]+)?))) {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, HEAD';
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With';
}
}
location @dynamic_request {
passenger_enabled on;
}
### END your own configuration options ###
}
passenger_pre_start <%= listen_url(app) %>;
<% end %>
<%= include_passenger_internal_template('footer.erb', 4) %>
}
Procfile
должен содержать строку:
web: bundle exec passenger start -p $PORT --max-pool-size 3 --nginx-config-template config/nginx.conf.erb
Вам также необходимо настроить CDN Cloudfront, который обслуживает активы в соответствии с Guapolo по ответ
в вашем дистрибутиве, который дает вам скорбь CORS, перейдите на вкладку поведения и новое поведение, выбрав путь к активу, т. е. /assets/icons.ttf и белый список "происхождение" согласно приведенному выше изображению.
вам также может потребоваться в дистрибутиве "аннулировать" старый кэшированный ресурс на вкладке invalidations, т. е. ввести полный актив и кэшированное имя из вашего инспектора и аннулировать. Однажды, что обработал, разверните приложение с конфигурацией и перезапустите heroku. Вам нужно будет открыть инспектор и "пустой кэш и жесткий перезагрузить" страницу.
надеюсь, что это работает - похоже, что конфигурация пассажира меняется время от времени, поэтому мы можем найти эти перерывы, и ответ нужно будет обновить, чтобы отразить новую конфигурацию.
Я не уверен, что это ответ, но, похоже, также можно попробовать самый простой способ, с помощью after_filter
С:
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'
...