2014-09-20 23 views
11

Tôi không thể nhận được Access-Control-Allow-Origin để hiển thị trong Chrome - mục tiêu cuối cùng của tôi là định cấu hình CORS cho phông chữ có Rails, vì vậy nó hoạt động trong production với CloudFront. Mặc dù bây giờ, tôi chỉ muốn làm cho nó hoạt động trong development. Tôi có thể thấy tiêu đề qua curl, chứ không phải Chrome.Làm cách nào để định cấu hình `Access-Control-Allow-Origin` bằng đường ray, nginx và hành khách?

Tôi đang sử dụng Rails 4.0, và tôi đã thử tất cả các nội dung sau ...

Tôi đã cấu hình Gemfileapplication.rb theo the rack-cors example for rails 4:

Gemfile

gem 'rack-cors', '~> 0.2.9', require: 'rack/cors' 

cấu hình /application.rb

config.middleware.insert_before 'ActionDispatch::Static', 'Rack::Cors' do 
    allow do 
     origins '*' 
     resource '*', 
      :headers => :any, 
      :methods => [:get, :options, :head] 
    end 
end 

ray 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) Công cụ cho nhà phát triển> Mạng> OpenSans-Regular-webfont.woff> Headers> Tiêu đề phản hồi

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 

Tôi cũng đã cố gắng lựa chọn thay thế sau đây, theo 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 

Tôi cũng đã thử các sau đây để applications.rb, theo 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' => '*'} 
} 

Tôi cũng đã cố gắng sau trong config.ru, như 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ó cào exec 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 

Tôi cũng đã cố gắng font_assets vô ích.

Trả lời

15

Dòng Server khiến tôi nghĩ rằng có lẽ là tài sản không được xử lý bởi Rails, mà là bởi nginx:

enter image description here

Điều này có nghĩa rằng các tiêu đề phải được bổ sung bởi nginx, không Rails, và do đó chúng ta cần phải cấu hình nginx. Hóa ra là the ability to configure nginx is possible as of Passenger 4.0.39 - (here is the corresponding Git diff). Tài liệu tương ứng có sẵn trong Passenger Standalone, under Advanced configuration.

Lưu ý quan trọng trong tài liệu: Tệp mẫu cấu hình gốc có thể thay đổi theo thời gian, ví dụ: bởi vì các tính năng mới được đưa vào Phusion Passenger. Nếu tệp mẫu cấu hình của bạn không chứa các thay đổi bắt buộc thì các tính năng mới này có thể không hoạt động đúng. Trong trường hợp xấu nhất, Standalone thậm chí có thể bị trục trặc. Do đó, mỗi lần bạn nâng cấp Phusion Passenger, bạn nên kiểm tra xem tệp mẫu cấu hình ban đầu đã thay đổi chưa và hợp nhất lại bất kỳ thay đổi nào vào tệp của riêng bạn.

đối với lưu ý rằng Với, ngoài các bản tùy biến của tập tin cấu hình, tạo ra một bản sao "gốc" mà bạn có thể diff bất cứ khi nào bạn nâng cấp hành khách.

bash

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

Tiếp theo, thêm --nginx-config-template config/nginx.conf.erb vào dòng web trong Procfile.

Procfile

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

config/nginx.conf.erb

Tiếp theo, chỉnh sửa file cấu hình config/nginx.conf.erb bằng cách tìm một khối trông như sau:

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

... và thêm hai dòng 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 *; 
    } 

Vậy đó. Điều này sẽ hoạt động trong production, nhưng không hoạt động trong development, do sự khác biệt giữa config.assets giữa hai loại.

cấu hình diff

Các diff không nên quay trở lại bất cứ điều gì bây giờ, nhưng nếu có bản cập nhật trong tương lai để hành khách bao gồm một sự thay đổi tập tin này, bạn sẽ biết.

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

tài liệu nginx

cải tiến tương lai

  • hạn chế Allow-Origin
  • hạn chế Request-Method
  • hạn chế cả tiêu đề để chỉ phông chữ
1

Tôi không chắc chắn rằng đó là câu trả lời, nhưng có vẻ như bạn cũng có thể thử cách đơn giản nhất với việc sử dụng after_filter với:

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! Cuối cùng.

của người dùng664833 answer above thật tuyệt, ngoại trừ tôi không thể tìm thấy tệp cấu hình Hành khách của mình để chỉnh sửa.

Thomas Nye của câu trả lời here cho toàn bộ tập tin để tạo ra tại config/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 nên bao gồm các dòng:

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

Bạn cũng sẽ cần để định cấu hình CDN Cloudfront đang phân phát nội dung theo Guapolo's answer

Configure CORS Cloudfront

Trong bản phân phối mang lại cho bạn nỗi đau CORS, chuyển đến tab hành vi và hành vi mới, chọn đường dẫn đến nội dung, ví dụ: /assets/icons.ttf và danh sách trắng 'Gốc' như trên hình ảnh.

Bạn cũng có thể cần, trong phân phối, 'làm mất hiệu lực' tài nguyên được lưu trong bộ nhớ cache cũ, nghĩa là đặt nội dung đầy đủ và tên được lưu trong bộ nhớ cache của thanh tra và vô hiệu. Khi đã xử lý xong, hãy triển khai ứng dụng bằng cấu hình và khởi động lại heroku. Bạn sẽ cần phải mở thanh tra và 'trống bộ nhớ cache và tải lại cứng' trang. Hy vọng rằng các công trình - có vẻ như các cấu hình hành khách thay đổi mỗi bây giờ và sau đó, vì vậy chúng tôi có thể tìm thấy sự phá vỡ này và câu trả lời sẽ cần phải được cập nhật để phản ánh cấu hình mới. Các tính năng chính của chúng tôi là:

Các vấn đề liên quan