Introduction
A content delivery network or content distribution network (CDN) is aimed at serving the content to end-users with high availability and high performance. There's a lot of good reasons about why to start using CDN, instead of hosting your own local copies of common JavaScript includes like jQuery and ASP.NET AJAX. According to Dave Ward, it decreases latency, increases parallelism and provides better caching. And of course, if this is offered as a free service, why wouldn’t you be using it ?
But wait a minute, what about if the CDN fails, due to an un-reliable internet connection? The pages will break without any JQuery or ASP.NET AJAX.
So, how do I avoid it? It's simple. We can always have a fallback mechanism in place for worst scenarios.
Solution for ASP.NET 4.5 Developers
ASP.NET 4.5 framework already includes the fallback mechanism for CDN outages. When using a ScriptManager
control in Web Forms, you can set EnableCdn="True"
and ASP.NET will automatically change the <script>
tags from using local scripts to using CDN-served scripts with local fallback checks included.
In the aspx page, we have to do this:
<asp:ScriptManager runat="server">
<Scripts>
<asp:ScriptReference Name="jquery" />
</Scripts>
</asp:ScriptManager>
In the global.ascx, we can add the script
mappings, like this:
string str = "2.0.0";
ScriptManager.ScriptResourceMapping.AddDefinition("jquery", new ScriptResourceDefinition
{
Path = "~/Scripts/jquery-" + str + ".min.js",
DebugPath = "~/Scripts/jquery-" + str + ".js",
CdnPath = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-" + str + ".min.js",
CdnDebugPath = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-" + str + ".js",
CdnSupportsSecureConnection = true,
LoadSuccessExpression = "window.jQuery"
});
And the output will look like this:
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.2.js"
type="text/javascript">
</script>
<script type="text/javascript">
(window.jQuery)||document.write('<script type="text/javascript"
src="Scripts/jquery-2.0.0.js"><\/script>');
</script>
Generic Solution
Here’s a generic solution for rest: in your page header, include the CDN reference, then check for a type or variable that should be present after a script load, and if it’s undefined, you can write out a reference to a copy that you’re hosting. Here’s how it looks:
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js"></script>
<script>
if (typeof jQuery == 'undefined') {
document.write(unescape("%3Cscript src='<%=ResolveClientUrl
("/Scripts/jquery-2.0.0.min.js")%>' type='text/javascript'%3E%3C/script%3E"));
}
</script>
Or, we can use this:
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js"></script>
<script>window.jQuery || document.write('<script src="<%=ResolveClientUrl
("/Scripts/jquery-2.0.0.min.js")%>">\x3C/script>')</script>
Or, if you want to specify multiple CDN, this is how you can:
<!--
<script src="http://www.codeproject.com/ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<!--
<script> window.jQuery || document.write('<script
src="http://www.codeproject.com/ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.0.min.js">
\x3C/script>')</script>
<!--
<script> window.jQuery || document.write('<script src="
<%=ResolveClientUrl("/Scripts/jquery-2.0.0.min.js")%>">
\x3C/script>')</script>
One easy way to test is to mangle the CDN references. You’ll get a HTTP 404 error due to the bad reference, but the fall-back reference will be loaded. You can verify this using FireBug.