Cloudfront CORS issue serving fonts on Rails application

后端 未结 5 2042
栀梦
栀梦 2021-01-31 10:07

I keep receiving this error message from the console when visiting my website:

font from origin \'https://xxx.cloudfront.net\' has been blocked from loading by C         


        
5条回答
  •  南方客
    南方客 (楼主)
    2021-01-31 10:15

    If you run Rails on Passenger and Heroku: (if not, jump straight to Noach Magedman's answer)

    Noach Magedman's answer was very useful for me to set up CloudFront properly.

    I also installed rack-cors exactly as described and whilst it worked fine in development, the CURL commands in production never returned any of the CORS configurations:

    curl -H "Origin: https://tidyme-staging.com.au" -I http://tidyme-staging.com.au/assets/31907B_4_0-588bd4e720d4008295dcfb85ef36b233ee0817d7fe23c76a3a543ebba8e7c85a.ttf
    
    HTTP/1.1 200 OK
    Connection: keep-alive
    Server: nginx/1.10.0
    Date: Wed, 03 Aug 2016 00:29:37 GMT
    Content-Type: application/x-font-ttf
    Content-Length: 316664
    Last-Modified: Fri, 22 Jul 2016 03:31:57 GMT
    Expires: Thu, 31 Dec 2037 23:55:55 GMT
    Cache-Control: max-age=315360000
    Cache-Control: public
    Accept-Ranges: bytes
    Via: 1.1 vegur
    

    Note that I ping the server directly without going through the CDN, the CDN then after invalidating all content should just forward whatever the server responds. The important line here is Server: nginx/1.10.0, which indicates that assets are served by nginx and not Rails. As a consequence, the rack-cors configurations do not apply.

    The solution that worked for us is here: http://monksealsoftware.com/ruby-on-rails-cors-heroku-passenger-5-0-28/

    It basically involved cloning and modifying the nginx config file for Passenger, which is not ideal since this copy needs to be maintained every time Passenger gets upgraded and the template changes.

    ===

    Here's a summary:

    Navigate to the root folder of your Rails project and make a copy of the nginx config template

    cp $(passenger-config about resourcesdir)/templates/standalone/config.erb config/passenger_config.erb
    

    Open config/passenger_config.erb and comment this line out

    <%# include_passenger_internal_template('rails_asset_pipeline.erb', 8, false) %>
    

    Add these configurations below the line mentioned above

    ### 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
    
    location ~ "^/assets/.+\.(woff|eot|svg|ttf|otf).*" {
        error_page 490 = @static_asset_fonts;
        error_page 491 = @dynamic_request;
        recursive_error_pages on;
    
        if (-f $request_filename) {
            return 490;
        }
        if (!-f $request_filename) {
            return 491;
        }
    }
    
    # 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 "";
    }
    
    location @static_asset_fonts {
        gzip_static on;
        expires max;
        add_header Cache-Control public;
        add_header ETag "";
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, HEAD, OPTIONS';
        add_header 'Access-Control-Allow-Headers' '*';
        add_header 'Access-Control-Max-Age' 3628800;
    }
    
    location @dynamic_request {
        passenger_enabled on;
    }
    
    ### END your own configuration options ###
    

    Change the Procfile to include this custom config file

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

    Then deploy...

    ===

    If you know of a better solution, please put in the comments.

    After implementing, the CURL command yielded the following response:

    curl -H "Origin: https://tidyme-staging.com.au" -I http://tidyme-staging.com.au/assets/31907B_4_0-588bd4e720d4008295dcfb85ef36b233ee0817d7fe23c76a3a543ebba8e7c85a.ttf
    
    HTTP/1.1 200 OK
    Connection: keep-alive
    Server: nginx/1.10.0
    Date: Wed, 03 Aug 2016 01:43:48 GMT
    Content-Type: application/x-font-ttf
    Content-Length: 316664
    Last-Modified: Fri, 22 Jul 2016 03:31:57 GMT
    Expires: Thu, 31 Dec 2037 23:55:55 GMT
    Cache-Control: max-age=315360000
    Cache-Control: public
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Methods: GET, HEAD, OPTIONS
    Access-Control-Allow-Headers: *
    Access-Control-Max-Age: 3628800
    Accept-Ranges: bytes
    Via: 1.1 vegur
    

提交回复
热议问题