No 'Access-Control-Allow-Origin' header is present on the requested resource?

12,798

Solution 1

You don't need to (shouldn't be) generating the headers in every response.

In your case, I would wager the asset request from your browser is being "preflighted" with an OPTIONS request, but the CDN passes on the request without Access-Control request headers. The CDN thus (correctly) receives no CORS response headers from your Rails app, so the browser doesn't even attempt the GET request, and fails with the Cross-Origin error.

"preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests

Your CDN needs be set up to forward the correct request headers to your app server such that it knows to generate the CORS headers. Then, the CDN will pass these CORS response headers along to the browser.

When you want OPTIONS responses to be cached, configure CloudFront to forward the following headers: Origin, Access-Control-Request-Headers, and Access-Control-Request-Method.

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-cors

If you make the change to your CDN for those headers and then invalidate your assets, your rack-cors configuration by itself should work just fine.

# config/initializers/cors.rb

# @note: must be run after initializers/_assets.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'

    # All asset requests should be to rails prefixed assets paths
    # serverd from the asset pipeline (e.g.: "/assets/*" by default)
    resource "#{Rails.application.config.assets.prefix}/*",
      # Allow any request headers to be sent in the asset request
      # https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Headers
      headers: :any,
      # All asset fetches should be via GET
      # Support OPTIONS for pre-flight requests
      # https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
      methods: [:get, :options]
  end
end

Solution 2

Try adding method and headers in application controller. It worked for me.

    def cors_set_access_control_headers
        headers['Access-Control-Allow-Origin'] = '*'
        headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, PATCH, OPTIONS'
        headers['Access-Control-Request-Method'] = '*'
        headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
    end
Share:
12,798
AnthonyGalli.com
Author by

AnthonyGalli.com

I'm building Live to Challenge. It's a ruby on rails goal-setting web app. I blog about my journey & lifestyle @ www.anthonygalli.com

Updated on June 05, 2022

Comments

  • AnthonyGalli.com
    AnthonyGalli.com about 2 years

    My bootstrap glyphicons show on other browsers, but I get this error on google chrome:

    Font from origin 'http://d37p52igaahgm9.cloudfront.net' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.anthonygalli.com' is therefore not allowed access.

    The error persists despite trying:

    application_controller.rb

    before_action :set_cors
    
    def set_cors
      headers['Access-Control-Allow-Origin'] = '*'
      headers['Access-Control-Request-Method'] = '*'
    end
    

    application.rb

    config.middleware.insert_before 0, "Rack::Cors" do
      allow do
        origins '*'
        resource '*', :headers => :any, :methods => [:get, :post, :options]
      end
    end
    
    config.action_dispatch.default_headers = {
        'Access-Control-Allow-Origin' => '*',
        'Access-Control-Request-Method' => '*'
    }
    

    CORS Configuration Editor

    <?xml version="1.0" encoding="UTF-8"?>
    <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
        <CORSRule>
            <AllowedOrigin>https://www.anthonygalli.com</AllowedOrigin>
            <AllowedMethod>GET</AllowedMethod>
            <MaxAgeSeconds>3000</MaxAgeSeconds>
            <AllowedHeader>Content-*</AllowedHeader>
            <AllowedHeader>Host</AllowedHeader>
        </CORSRule>
        <CORSRule>
            <AllowedOrigin>https://anthonygalli.com</AllowedOrigin>
            <AllowedMethod>GET</AllowedMethod>
            <MaxAgeSeconds>3000</MaxAgeSeconds>
            <AllowedHeader>Content-*</AllowedHeader>
            <AllowedHeader>Host</AllowedHeader>
        </CORSRule>
    </CORSConfiguration>
    

    REFERENCES