alt='font cdn cors'

Azure CDN-ing a non-standard font

So, you need to CDN your Intranet Episerver app? Good, but what when you have a non-standard font?

If you'd like to read more about how Azure CDN can be used in an Episerver project, read my previous blogpost. The differences in approach with a public and an Intranet are explained there as well. All the challenges we have had with an Intranet are covered, other than the font that has to be hosted in the Azure blob.

We have used cloudflare fonts/css/js for all the files we could. However, a custom font was not available on cloudflare or on any other public CDN. So, instead, we had to host it directly on Azure - in a blob, that we then "CDN-ed". 

That looked like a good approach, except - these "CDN-ed" fonts didn't work! :D The console error was  "No 'Access-Control-Allow-Origin' header is present on the requested resource in chrome." When inspecting further (either with console or Fiddler), the header is missing. 

The solution is to add CORS - "Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another domain outside the domain from which the resource originated."  So, here is an initializable module that does exactly that:
 
[InitializableModule]
    public class CorsInitializableModule : IInitializableModule
    {
        public void Initialize(InitializationEngine context)
        {
            var blobClient = GetBlobClient();
            if (blobClient != null)
            {
                AddAllowedOrigins(blobClient);
            }
        }

        private static CloudBlobClient GetBlobClient()
        {
            CloudStorageAccount csa;
            CloudStorageAccount.TryParse(ConfigurationManager.AppSettings["StorageConnectionString"], out csa);
            
            if (csa != null)
            {
                return csa.CreateCloudBlobClient();
            }

            return null;
        }

        private static void AddAllowedOrigins(CloudBlobClient blobClient)
        {
            var serviceProperties = blobClient.GetServiceProperties();

            serviceProperties.Cors = new CorsProperties();
            serviceProperties.Cors.CorsRules.Add(new CorsRule
            {
                AllowedHeaders = new List { "*" },
                AllowedMethods = CorsHttpMethods.Put | CorsHttpMethods.Get | CorsHttpMethods.Head | CorsHttpMethods.Post,
                AllowedOrigins = new List { "*" },
                ExposedHeaders = new List { "*" },
                MaxAgeInSeconds = 1800 // 30 minutes
            });

            blobClient.SetServiceProperties(serviceProperties);
        }

        public void Uninitialize(InitializationEngine context)
        {
        }
    }

Do note that if you already have this issue, it might be easier for you to delete the blobs, then upload them before you access CDN URL-s again, otherwise you will have to wait and see if your changes had an affect. 

comments powered by Disqus