DevTrends

Azure

Hosting Web Fonts in Azure Blob Storage using the new CORS Support

We have been waiting a long time for CORS support on Windows Azure Blob Storage but the wait is now over. This post describes how to enable CORS allowing you to serve web fonts from Azure Blob Storage and the Azure CDN.

This post originally appeared on the FeedbackHound Blog. Feedbackhound is now focused on android development, so we have moved all .NET posts back to DevTrends.

Background

If you care about website performance, you probably know that using a content delivery network (CDN) is highly recommended. Serving CSS, JS and images from a CDN is easy enough but modern sites often use web fonts and these can cause issues when hosted on a CDN.

If you try and use a font that is hosted on another domain then in many browsers you will see an error and the font will not work.

CORS error

This is due to the Cross-Origin Resource Sharing (CORS) standard which is implemented in most browsers today (Chrome implements CORS but unlike other browsers, it does not apply it to web fonts). CORS only allows you to access remote resources such as web fonts if the resource is served with a special header:

Access-Control-Allow-Origin:*

Access-Control-Allow-Origin:blah.com

Google Fonts and other hosted font providers automatically handle this for you but if you want to serve your own fonts from a CDN, you have to implement it yourself.

CDN Options in Azure

If you are using Windows Azure then depending on your hosting choice, there are a couple of options available for a CDN.

If you are using a Cloud Service Web Role (not a Windows Azure Web Site), you can get the CDN to pull content from a folder within your website. This is nice and easy and gives you full control over headers. Enabling CORS is as simple as a change to your web.config:

<configuration>
  <system.webServer>
    <rewrite>
      <outboundRules>
        <rule name="Set Access-Control-Allow-Origin header">
          <match serverVariable="RESPONSE_Access-Control-Allow-Origin" pattern="(.*)" />
          <action type="Rewrite" value="*" />
        </rule>
      </outboundRules>
    </rewrite>
  </system.webServer>
</configuration>

This has been a option for a long time but it cannot be used in all cases. If you are using Windows Azure Web Sites (WAWS) or if the first option is not suitable for your scenario, there is a second option. This is to allow the Azure CDN to pull content from Azure Blob Storage.

Enabling CORS for Azure Blob Storage

Until recently, it was not possible to add CORS headers to resources stored in blob storage, making it impossible to serve web fonts. With the latest updates released in the last few days, this has changed (at last :-)). At the time of writing, there is no UI to enable CORS so you can either call the REST API directly or do it via the Windows Azure Storage client library available on NuGet. This post covers enabling CORS using the client library.

You will need to update to version 3.0 to enable CORS.

Once you have upgraded, simply execute the following code:

private void ConfigureCors(CloudStorageAccount storageAccount)
{
  var blobClient = storageAccount.CreateCloudBlobClient();

  var serviceProperties = blobClient.GetServiceProperties();

  var cors = new CorsRule();

  cors.AllowedOrigins.Add("*");
  //cors.AllowedOrigins.Add("mysite.com"); // more restrictive may be preferable
  cors.AllowedMethods = CorsHttpMethods.Get;
  cors.MaxAgeInSeconds = 3600;

  serviceProperties.Cors.CorsRules.Add(cors);            

  blobClient.SetServiceProperties(serviceProperties);
}

As far as I can tell, this is a one off requirement so you can execute it locally and then delete it (or comment out the code in case you need to change your settings in the future). If you need to configure more than simple GET support then you can find out much more on MSDN.

Useful or Interesting?

If you liked the article, we would really appreciate it if you would share it with your Twitter followers.

Share on Twitter »

Comments

Comments are now closed for this article.