Search code examples
htmlruby-on-railscorsrack-cors

Rails cors issue with JS files and URL rewrite


In my root domain (example.com), I entered a rewrite rule using Render UI so that users visiting example.com/library will see the application hosted on library.example.com.

enter image description here

Now, when visiting example.com/library, the JS is not loaded because of a CORS error. Instead, the CSS is loaded successfully.

enter image description here

I use Rails importmap, if relevant.

<script type="importmap" data-turbo-track="reload">{
  "imports": {
    "application": "https://library.example.com/assets/application-ec9fb8976583666f9882e99ffe94f0391fc9ac4f1a32034d128201c87ac33ca3.js",
    "@hotwired/turbo-rails": "https://library.example.com/assets/turbo.min-dfd93b3092d1d0ff56557294538d069bdbb28977d3987cb39bc0dd892f32fc57.js",
    "posthog-js": "https://library.example.com/assets/posthog-js-27c6009e7053c1cc4ca4881a8510159e64330186618212ecf07859f877b74651.js",
    "posthog-custom": "https://library.example.com/assets/src/posthog-e818ed81c53c6838d2ee7e8efc4f6faaf02a31bc3ea7e95fe0b56eacbdd4c025.js",
    "video-custom": "https://library.example.com/assets/src/video-eefb06ba48956b0b5d08542119b3782b256b09daf694e20c8de3164ca020c541.js"
  }
}</script>

This is the full URL of a JS file: GET https://library.example.com/assets/application-ec9fb8976583666f9882e99ffe94f0391fc9ac4f1a32034d128201c87ac33ca3.js

Request headers

  • :authority: library.example.com
  • :method: GET
  • :path: /assets/applicationec9fb8976583666f9882e99ffe94f0391fc9ac4f1a32034d128201c87ac33ca3.js
  • :scheme: https
  • accept: /
  • accept-encoding: gzip, deflate, br, zstd
  • accept-language: it
  • cache-control: no-cache
  • dnt: 1
  • origin: https://www.example.com
  • pragma: no-cache
  • priority: u=1
  • referer: https://www.example.com/
  • sec-ch-ua: "Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"
  • sec-ch-ua-mobile: ?0
  • sec-ch-ua-platform: "macOS"
  • sec-fetch-dest: script
  • sec-fetch-mode: cors
  • sec-fetch-site: same-site
  • user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36

Response headers

  • age: 12
  • cache-control: public, max-age=14400
  • cf-cache-status: HIT
  • cf-ray: m8c589566aaca599b-MXP
  • content-encoding: mgzip
  • content-type: application/javascript
  • date: Thu, 19 Sep 2024 09:35:04 GMT
  • etag: W/"66e18820-b8"
  • expires: Thu, 19 Sep 2024 13:35:04 GMT
  • last-modified: Wed, 11 Sep 2024 12:08:00 GMT
  • server: cloudflare
  • vary: Accept-Encoding
  • x-powered-by: cloud66

I have added this on the Ruby on Rails app hosted on library.example.com.

/config/application.rb

config.middleware.insert_before 0, Rack::Cors do

      allow do
        origins 'https://www.example.com','https://example.com'
        resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head]
      end

end

but isn't working.

I expect no errors in dev console and I must be able to visit example.com/library and load the page served from library.example.com with all CSS and JS.


Solution

  • SOLVED. After a few days, here all the settings needed to make it work.

    Cloudflare

    Bot flight mode was blocking the request. So, I solved with a WAF Rule

    Cloudflare > Security > WAF

    1. IF hostname=library.example.com THEN skip All Super Bot Fight Mode Rules
    2. IF path=/library THEN skip All Super Bot Fight Mode Rules

    Render

    Order is important. Be sure to add a rewrite rule for your assets.

    enter image description here

    CLOUD66

    enter image description here

    Ruby on Rails

    /app/config/enviroment/production.rb

      config.asset_host = "https://www.example.com/library"
      config.action_mailer.default_url_options = { host: "https://www.example.com" }
      Rails.application.routes.default_url_options = { host: "https://www.example.com" }
    

    config/routes.rb

    resources :my_resource, only: [:index], path: '/library' do
    

    app/controllers/application_controller.rb

    class ApplicationController < ActionController::Base
      def default_url_options
        { host: Rails.application.config.action_mailer.default_url_options[:host] }
      end
    end