Microsoft's XMLHttpRequest ActiveX Objects
This is an excerpt from my book, Accelerated DOM Scripting available at Amazon and other fine retailers. Although it's only a small section of the book, it's one of my favourite pieces because it had always been a mystery to me.
If you’ve scoured through any number of Ajax solutions, you might have noticed different XMLHttpRequest objects being referred to. Microsoft’s XML implementation is known as MSXML and comes in many versions.
Here’s the list:
- Microsoft.XMLHTTP
- Msxml2.XMLHTTP
- Msxml2.XMLHTTP.3.0
- Msxml2.XMLHTTP.4.0
- Msxml2.XMLHTTP.5.0
- Msxml2.XMLHTTP.6.0
An article from the Microsoft XML team explains in some detail the differences between what the different versions are and how they should be used (but it’s still not entirely clear).
MSXML 1.0 and 2.0 are no longer supported by Microsoft. Version 4.0 never saw an operating system release, and version 5.0 was a special version for Microsoft Office. The version-independent IDs, Microsoft.XMLHTTP and Msxml2.XMLHTTP, now map directly to version 3.0 (even if version 6.0 is installed). This really only leaves you with two possible program IDs (referred to as progIDs by Microsoft):
- Msxml2.XMLHTTP
- Msxml2.XMLHTTP.6.0
Version 6 was introduced in IE 7 and includes some bug fixes such as the one where IE 5 and 6 fail when the onreadystatechange is declared before the open call. Although IE 7 includes a native XHR object, users have the option of disabling it. Therefore, it’s a good idea to test for Msxml2.XMLHTTP.6.0 first; if it doesn’t work, fall back to the other version.
Here's a quick example checking for the native object before checking for the IE-specific versions:
/**
Will return a valid object if successful
*/
function XHR()
{
var transport;
// check native support first
if(window.XMLHttpRequest) {
transport = new XMLHttpRequest();
}else{
// check for version 6 before version 3
try{ transport = new ActiveXObject("MSXML2.XMLHTTP.6.0"); }catch(e){}
try{ if(!transport) transport = new ActiveXObject("MSXML2.XMLHTTP"); }catch(e){}
}
return transport;
}
Conversation
It's good to have these listed. and to understand what they really are!
Nitpicking, just one small thing: given Douglas Crockford's and others' advice, do you really want the starting
{
on a separate line?Short example: JavaScript Style - why it’s important
Yes, I still prefer putting the { on a new line. I find it easier for seeing where my functions start and end. For
return
s, I don't like returning an object literal, so I'll always assign it to a variable and then return the variable. I find the code more readable that way and, as it turns out, avoids the issue described.Shouldn't the order of those lines be reversed? That way IE7 users with the XHR object disabled will get the 6.0 instead of the 3.0. Or am I not following? It seems to me that, in IE7 with XHR disabled, the first statement will succeed and the transport variable will reference the 6.0 version. And then the second statement will also succeed and the transport variable will now reference the 3.0 version.
@Chris A: Good catch. I've updated the code example in the article with an IF check in the second TRY statement. (Now to put together my first errata for the book...)
I usually return the object as soon as possible i.e.
Yes, that solves that specific issue. But to me, at least, it seems like sound advice to always have it on the same line as the code, to avoid any potential hazards with semi-colons inserted automatically by the interpretor.
Very nice!
Robert,
There are no known issues with having your beginning bracket on a new line and accidental semi-colon insertion when dealing with functions, for/while-loops, if/then statements, etc in JavaScript. Even Crockford does some of his code this way.
The issue comes into focus when you are dealing with objects.
I should correct my last statement above to say:
The issue comes into focus when you are dealing with literals.
Breaking after a parenthesis is perfectly fine.
Being an ECMAScript Engine author, I shall call you on that.
Semicolons are technically *required* after break, continue, return and throw statements, and newline is now allowed between break and any following identifier token. Any engine which assumes a newline after a break is a semicolon is violating standard.
When I code in it, I always explicitly write it;
I might also mention that:
if(window.XMLHttpRequest)
return new XMLHttpRequest();
else if(window.ActiveXObject)
return new ActiveXObject("msxml2.xmlhttp");
else
throw new Error("Could not find XMLHttpRequest Object");
works fine, provided you remember to put open before onreadystatechange.
Regards,
Dan
Hi! Ebanij vrot! tb7oh8ki77 vn254iax6g!
ceea ce I was privire pentru, multumesc