What would be a good way to attempt to load the hosted jQuery at Google (or other Google hosted libs), but load my copy of jQuery if the Google attempt fails?
I\'m n
jQuery
variable)How to check a not-defined variable in JavaScript
How do I include a JavaScript file in another JavaScript file?
Because of the Google's banning problem I prefer to use Microsoft's cdn http://www.asp.net/ajaxlibrary/cdn.ashx
UPDATE:
This answer turned out to be wrong. Please see the comments for the real explanation.
Most of you question has been answered, but as for the final part:
What would be the danger of both copies coming through?
None really. You'd waste bandwidth, might add some milliseconds downloading a second useless copy, but there's not actual harm if they both come through. You should, of course, avoid this using the techniques mentioned above.
Yet another fallback that replaces ajax.googleapis.com with cdnjs.cloudflare.com:
(function (doc, $)
{
'use strict';
if (typeof $ === 'undefined')
{
var script = doc.querySelector('script[src*="jquery.min.js"]'),
src = script.src.replace('ajax.googleapis.com', 'cdnjs.cloudflare.com');
script.parentNode.removeChild(script);
doc.write('<script src="' + src + '"></script>');
}
})(document, window.jQuery || window.Zepto);
Using Razor syntax in ASP.NET, this code provides fallback support and works with a virtual root:
@{var jQueryPath = Url.Content("~/Scripts/jquery-1.7.1.min.js");}
<script type="text/javascript">
if (typeof jQuery == 'undefined')
document.write(unescape("%3Cscript src='@jQueryPath' type='text/javascript'%3E%3C/script%3E"));
</script>
Or make a helper (helper overview):
@helper CdnScript(string script, string cdnPath, string test) {
@Html.Raw("<script src=\"http://ajax.aspnetcdn.com/" + cdnPath + "/" + script + "\" type=\"text/javascript\"></script>" +
"<script type=\"text/javascript\">" + test + " || document.write(unescape(\"%3Cscript src='" + Url.Content("~/Scripts/" + script) + "' type='text/javascript'%3E%3C/script%3E\"));</script>")
}
and use it like this:
@CdnScript("jquery-1.7.1.min.js", "ajax/jQuery", "window.jQuery")
@CdnScript("jquery.validate.min.js", "ajax/jquery.validate/1.9", "jQuery.fn.validate")
This seems to work for me:
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
// has the google object loaded?
if (window.google && window.google.load) {
google.load("jquery", "1.3.2");
} else {
document.write('<script type="text/javascript" src="http://joecrawford.com/jquery-1.3.2.min.js"><\/script>');
}
window.onload = function() {
$('#test').css({'border':'2px solid #f00'});
};
</script>
</head>
<body>
<p id="test">hello jQuery</p>
</body>
</html>
The way it works is to use the google
object that calling http://www.google.com/jsapi loads onto the window
object. If that object is not present, we are assuming that access to Google is failing. If that is the case, we load a local copy using document.write
. (I'm using my own server in this case, please use your own for testing this).
I also test for the presence of window.google.load
- I could also do a typeof
check to see that things are objects or functions as appropriate. But I think this does the trick.
Here's just the loading logic, since code highlighting seems to fail since I posted the whole HTML page I was testing:
if (window.google && window.google.load) {
google.load("jquery", "1.3.2");
} else {
document.write('<script type="text/javascript" src="http://joecrawford.com/jquery-1.3.2.min.js"><\/script>');
}
Though I must say, I'm not sure that if this is a concern for your site visitors you should be fiddling with the Google AJAX Libraries API at all.
Fun fact: I tried initially to use a try..catch block for this in various versions but could not find a combination that was as clean as this. I'd be interested to see other implementations of this idea, purely as an exercise.