simonk  
                (Simon King)
               
              
                  
                    October 28, 2024, 11:49am
                   
                   
              4 
               
             
            
              Are you using a CDN on either of these sites? I have noticed that code highlighting is no longer working on my site, and I think it’s because of this:
  
  
    The change which made this noticeable was most likely DEV: Modernise highlightjs loading (#24197) · discourse/discourse@0878dde · GitHub , which switched highlightjs to load via native import(), which requires CORS headers when fetching from a CDN. 
But even before that change, you likely would have had some issues with things like custom Fonts (which also require CORS headers for cross-origin requests). 
In theory, Discourse itself should be adding the CORS header to CDN responses. If it’s not, …
   
 
In my case, my CDN is not  returning an Access-Control-Allow-Origin header for the highlightjs file. I notice that Meta’s CDN does  include that header, so I wonder what is different.
$ curl --silent -I https://d3bpeqsaub0i6y.cloudfront.net/highlight-js/meta.discourse.org/9797975efac87d28baa695ae13ca72ccaf5120f5.js | grep -i access-control
access-control-allow-origin: *
access-control-allow-methods: GET, HEAD, OPTIONS
 
However, those headers are not  being served by the origin server:
$ curl --silent -I https://meta.discourse.org/highlight-js/meta.discourse.org/9797975efac87d28baa695ae13ca72ccaf5120f5.js | grep -i access-control
<no output>
 
As far as I can tell, Discourse is meant to add access-control headers to the highlightjs files:
  
  
    
    
      
          # frozen_string_literal: true 
           
          class HighlightJsController < ApplicationController 
            skip_before_action :preload_json, 
                               :redirect_to_login_if_required, 
                               :redirect_to_profile_if_required, 
                               :check_xhr, 
                               :verify_authenticity_token, 
                               only: [:show] 
           
            before_action :apply_cdn_headers, only: [:show] 
           
            def show 
              no_cookies 
           
              RailsMultisite::ConnectionManagement.with_hostname(params[:hostname]) do 
                current_version = HighlightJs.version(SiteSetting.highlighted_languages) 
           
                return redirect_to path(HighlightJs.path) if current_version != params[:version] 
           
                # note, this can be slightly optimised by caching the bundled file, it cuts down on N reads 
       
     
   
  
    
    
  
  
 
However , those headers are only applied if the request is a “CDN request”:
  
  
    
    
      
            return unless mini_profiler_enabled? 
            Rack::MiniProfiler.authorize_request 
          end 
           
          def check_xhr 
            # bypass xhr check on PUT / POST / DELETE provided api key is there, otherwise calling api is annoying 
            return if !request.get? && (is_api? || is_user_api?) 
            raise ApplicationController::RenderEmpty.new if !request.format&.json? && !request.xhr? 
          end 
           
          def apply_cdn_headers 
            if Discourse.is_cdn_request?(request.env, request.method) 
              Discourse.apply_cdn_headers(response.headers) 
            end 
          end 
           
          def self.requires_login(arg = {}) 
            @requires_login_arg = arg 
          end 
           
          def self.requires_login_arg 
       
     
   
  
    
    
  
  
 
  
  
    
    
      
          end 
           
          mattr_accessor :redis 
           
          def self.is_parallel_test? 
            ENV["RAILS_ENV"] == "test" && ENV["TEST_ENV_NUMBER"] 
          end 
           
          CDN_REQUEST_METHODS ||= %w[GET HEAD OPTIONS] 
           
          def self.is_cdn_request?(env, request_method) 
            return if CDN_REQUEST_METHODS.exclude?(request_method) 
           
            cdn_hostnames = GlobalSetting.cdn_hostnames 
            return if cdn_hostnames.blank? 
           
            requested_hostname = env[REQUESTED_HOSTNAME] || env[Rack::HTTP_HOST] 
            cdn_hostnames.include?(requested_hostname) 
          end 
           
          def self.apply_cdn_headers(headers) 
       
     
   
  
    
    
  
  
 
This only works if Discourse is configured with a separate host name for “CDN requests”.
             
            
               
               
              1 Like