2014-09-20 18 views
11

Ich kann nicht Access-Control-Allow-Origin in Chrome angezeigt werden - mein ultimatives Ziel ist es, CORS für Schriftarten mit Rails zu konfigurieren, so funktioniert es in production mit CloudFront. Aber jetzt will ich es nur in development zum Laufen bringen. Ich kann die Kopfzeile über curl sehen, aber nicht Chrome.Wie konfiguriere ich `Access-Control-Allow-Origin` mit Rails, Nginx und Passenger?

Ich verwende Rails 4.0, und ich habe alle folgenden versucht ...

Ich habe konfiguriert Gemfile und application.rb gemäß 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 

Schienen Konsole

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> Netzwerk> OpenSans-Regular-webfont.woff> Kopf-> Antwort-Header

Ich habe auch versucht die folgenden Alternativen, wie pro 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 

Ich habe auch versucht die folgenden applications.rb, wie pro 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' => '*'} 
} 

Ich habe versucht, auch die folgenden in config.ru, wie per CloudFront CDN with Rails on Heroku

require 'rack/cors' 
use Rack::Cors do 
    allow do 
     origins '*' 
     resource '*', :headers => :any, :methods => :get 
    end 
end 

Bündel 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 

Ich habe auch versucht font_assets ohne Erfolg.

Antwort

15

Die Server Linie machte mich denken, dass vielleicht das Vermögen nicht durch Rails umgegangen wird, sondern durch nginx:

enter image description here

Dies bedeutet, dass die Header von nginx hinzugefügt werden müssen, nicht Rails, und deshalb müssen wir nginx konfigurieren. Es stellt sich heraus, dass the ability to configure nginx is possible as of Passenger 4.0.39 - (here is the corresponding Git diff). Die entsprechende Dokumentation finden Sie unter Passenger Standalone, under Advanced configuration.

Ein wichtiger Hinweis in der Dokumentation: Die ursprüngliche Konfigurationsvorlagendatei kann sich von Zeit zu Zeit ändern, z. weil neue Funktionen in Phusion Passenger eingeführt werden. Wenn die Konfigurationsvorlagendatei nicht die erforderlichen Änderungen enthält, funktionieren diese neuen Funktionen möglicherweise nicht ordnungsgemäß. Im schlimmsten Fall könnte die Standalone sogar fehlschlagen. Daher sollten Sie bei jedem Upgrade von Phusion Passenger prüfen, ob sich die ursprüngliche Konfigurationsvorlagendatei geändert hat, und etwaige Änderungen in Ihre eigene Datei zurückführen.

Im Hinblick auf diese Note, zusätzlich zu der individuell anpassbaren Kopie der Konfigurationsdatei, erstellen Sie eine „Original“ Kopie, die Sie diff können, wann immer Sie Passagier aktualisieren.

bash

cp $(passenger-config about resourcesdir)/templates/standalone/config.erb config/nginx.conf.erb 
cp config/nginx.conf.erb config/nginx.conf.erb.original 

Als Nächstes fügen --nginx-config-template config/nginx.conf.erb zum web Linie in Procfile.

procfile

web: bundle exec passenger start -p $PORT --max-pool-size 3 --nginx-config-template config/nginx.conf.erb 

config/nginx.conf.erb

Als nächstes bearbeiten Sie die Konfigurationsdatei config/nginx.conf.erb durch einen Block zu finden, die wie folgt aussieht:

location @static_asset { 
     gzip_static on; 
     expires max; 
     add_header Cache-Control public; 
     add_header ETag ""; 
    } 

... und füge die zwei Access-Control Zeilen hinzu:

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 *; 
    } 

Das ist es. Dies funktioniert in production, aber nicht in development, aufgrund config.assets Unterschiede zwischen den beiden.

die Config diff

Die diff sollte jetzt nichts zurück, aber wenn alle zukünftigen Updates Passagier eine Änderung an dieser Datei enthalten, werden Sie wissen.

diff $(passenger-config about resourcesdir)/templates/standalone/config.erb config/nginx.conf.erb.original 

nginx Dokumentation

zukünftige Verbesserungen

  • beschränken die Allow-Origin
  • die gerade Request-Method
  • beide Header beschränken beschränken Schriften
1

Ich bin nicht sicher, dass es Antwort ist, aber es sieht aus wie Sie auch bei der Verwendung von after_filter mit den einfachsten Weg versuchen könnte:

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' 
... 
2

YES! Endlich.

user664833 ist answer above ist großartig, außer ich konnte meine Passenger Config-Datei zum Bearbeiten nicht finden.

Thomas Nye Antwort here gibt die vollständige Datei auf Config erstellen/nginx.conf.erb:

########################################################################## 
# 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 die Zeile enthalten sollte:

web: bundle exec passenger start -p $PORT --max-pool-size 3 --nginx-config-template config/nginx.conf.erb

Sie auch benötigen Konfigurieren Sie Ihr Cloudfront-CDN, das die Assets gemäß Guapolo's answer

bereitstellt Configure CORS Cloudfront

In Ihrer Distribution, die Ihnen CORS Trauer schenkt, gehen Sie auf die Registerkarte Verhalten und ein neues Verhalten, die Auswahl der Pfad zu dem Vermögenswert, dh /assets/icons.ttf und Weiße Liste ‚Origin‘ gemäß dem oben Bild.

Möglicherweise müssen Sie auch in Ihrer Distribution die alte zwischengespeicherte Ressource auf der Registerkarte "Invalidierungen" "ungültig machen", d. H. Den vollständigen Inhalt und den zwischengespeicherten Namen aus Ihrem Inspektor einfügen und ungültig machen. Sobald dies geschehen ist, deployen Sie die App mit der Config und starten Sie heroku neu. Sie müssen den Inspektor öffnen und die Seite leeren und die Seite neu laden.

Hoffentlich funktioniert das - es klingt wie die Passagierkonfiguration ändert sich hin und wieder, so können wir finden, dass dies bricht und die Antwort muss aktualisiert werden, um die neue Konfiguration widerzuspiegeln.

Verwandte Themen