Shorter XHR Abstraction
Ajaxian posted about Nicolas Faugout's approach to abstract the XMLHttpRequest object.
if (!XMLHttpRequest) {
function XMLHttpRequest() {
return new ActiveXObject('Microsoft.XMLHTTP');
}
}
The problem, as pointed out in the comments of that article is that Internet Explorer declares the function before it runs the code. In Firefox (and possibly others), it doesn't. Therefore, it seems like this works. The problem is that IE7 now has a native XHR object. This code doesn't take that into account and would overwrite the native object and try to use the ActiveX object. If users have ActiveX objects disabled in IE7, they'll be out of luck and won't be able to use your fancy Ajax.
Is there another way? Leave it to conditional comments to come to the rescue:
/*@cc_on
@if (@_jscript_version >= 5 && @_jscript_version < 5.7)
function XMLHttpRequest() {
try{
return new ActiveXObject(Msxml2.XMLHTTP');
}catch(e){}
}
@end
@*/
The conditional comments get turned on and ensure that no other browser but Internet Explorer will recognize and run this code. Furthermore, it checks the version of JScript to make sure it's within a specific range. Jscript 5.7 is the version that shipped with IE7; which, of course, is the version with the native XHR object.
I even threw in the try/catch block so that it doesn't throw an automation error in IE6 if the object doesn't exist.
In doing some research to see how other people may have attacked this problem, you can check out the following:
- Which function to get an XMLHttpRequest object? (Andrea Giammarchi)
- Shortest way to create an XMLHttpRequest object (Stuart Langridge)
So, can you improve on this? Is it possible to make it shorter?
Conversation
Elad just left a comment on the Ajaxian article:
It should probably still have the try/catch block but otherwise. This should work.
The Ajaxian thing has trackbacks to 3 new blog entries with titles of "blah blah XHR abstraction blah blah blah"
Perhaps, to emphasize the fact that it's an abstraction, and because everyone's using the term
anyway, you could go with the compact:Then, when programmers use
new XHR()
it's obvious they're not necessarily getting a native implementation ofXMLHttpRequest
.It's just a thought.
@Ash: the question is, should any need to adjust implementation -- such as enabling addEventListener functionality in IE -- warrant an abstraction of the whole process? Certainly that's what most libraries do: build an API on top of an API.
Needless to say, it sounds like the true problem isn't the abstraction, but a better use of branching. Branching shouldn't happen upon every request, but rather once at runtime of the page.
Although I agree with you in general Dustin, you'll have to admit that the bottle-neck in an Ajax request certainly isn't the branching.
MS is now shipping the 5.7 scripting engine as a standalone install.
http://blogs.msdn.com/jscript/archive/2007/08/12/windows-script-5-7-released-for-windows-2000-windows-xp-and-windows-2003-server.aspx
I suspect this means that someone running IE6 might now also have JS 5.7. In this case your sniff code won't define the needed ctor.
objREQ = window.ActiveXObject == false ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP") ;