这两天闲着没事,看了一些自己以前写的js代码,对创建XmlHttpRequest核心对象的js写法产生了兴趣,原先只知道针对不同浏览器,创建XHR对象的方法不同,但一直没有进行系统的整理和阐述。现将网上查到的和我自己整理的列举如下:
通常,在我的ASP.NET程序中,我通常这样创建XHR对象:

Code
var xmlHttp;
function createXMLHttpRequest()
{
if (window.ActiveXObject) //IE浏览器
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) //Mozilia浏览器
{
xmlHttp = new XMLHttpRequest();
}
}
从上面我们可以知道,目前主要针对浏览器内核的不同,采取不同的方式创建XHR对象。
对于IE浏览器,Microsoft 浏览器 Internet Explorer 使用 MSXML 解析器处理 XML。因此如果编写的 Ajax 应用程序要和 Internet Explorer 打交道,那么必须用一种特殊的方式创建对象。方法如下:
var xmlHttp = false;

try
{
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

} catch (e)
{

try
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

} catch (e2)
{
xmlHttp = false;
}
}

而对于非IE内核浏览器,需要使用不同的代码。事实上就是如下所示的简单代码:
var xmlHttp = new XMLHttpRequest();
这行简单得多的代码在 Mozilla、Firefox、Safari、Opera 以及基本上所有以任何形式或方式支持 Ajax 的非 Microsoft 浏览器中,创建了 XMLHttpRequest 对象。
后来发现,我这个写法是最基础的,而XMLHTTP组件这几年又随着OS的更新而不断升级,推出了很多新的版本。在我的TopMapTest项目中,我找到我原来用过的一个xmlextra.js封装的脚本库发现,在这个功能类中,也提供了对不同浏览器创建XHR对象的扩展,其内容为:

Code
//<script>
//////////////////
// Helper Stuff //
//////////////////

// used to find the Automation server name

function getDomDocumentPrefix()
{
if (getDomDocumentPrefix.prefix)
return getDomDocumentPrefix.prefix;
var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
var o;

for (var i = 0; i < prefixes.length; i++)
{

try
{
// try to create the objects
o = new ActiveXObject(prefixes[i] + ".DomDocument");
return getDomDocumentPrefix.prefix = prefixes[i];
}

catch (ex)
{};
}
throw new Error("Could not find an installed XML parser");
}


function getXmlHttpPrefix()
{
if (getXmlHttpPrefix.prefix)
return getXmlHttpPrefix.prefix;
var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
var o;

for (var i = 0; i < prefixes.length; i++)
{

try
{
// try to create the objects
o = new ActiveXObject(prefixes[i] + ".XmlHttp");
return getXmlHttpPrefix.prefix = prefixes[i];
}

catch (ex)
{};
}
throw new Error("Could not find an installed XML parser");
}

//////////////////////////
// Start the Real stuff //
//////////////////////////


// XmlHttp factory

function XmlHttp()
{}


XmlHttp.create = function ()
{

try
{

if (window.XMLHttpRequest)
{
var req = new XMLHttpRequest();
// some versions of Moz do not support the readyState property
// and the onreadystate event so we patch it!

if (req.readyState == null)
{
req.readyState = 1;

req.addEventListener("load", function ()
{
req.readyState = 4;
if (typeof req.onreadystatechange == "function")
req.onreadystatechange();
}, false);
}
return req;
}

if (window.ActiveXObject)
{
return new ActiveXObject(getXmlHttpPrefix() + ".XmlHttp");
}
}

catch (ex)
{}
// fell through
throw new Error("Your browser does not support XmlHttp objects");
};

// XmlDocument factory

function XmlDocument()
{}


XmlDocument.create = function ()
{

try
{
// DOM2

if (document.implementation && document.implementation.createDocument)
{
var doc = document.implementation.createDocument("", "", null);
// some versions of Moz do not support the readyState property
// and the onreadystate event so we patch it!

if (doc.readyState == null)
{
doc.readyState = 1;

doc.addEventListener("load", function ()
{
doc.readyState = 4;
if (typeof doc.onreadystatechange == "function")
doc.onreadystatechange();
}, false);
}
return doc;
}
if (window.ActiveXObject)
return new ActiveXObject(getDomDocumentPrefix() + ".DomDocument");
}

catch (ex)
{}
throw new Error("Your browser does not support XmlDocument objects");
};

// Create the loadXML method and xml getter for Mozilla
if (window.DOMParser &&
window.XMLSerializer &&

window.Node && Node.prototype && Node.prototype.__defineGetter__)
{

// XMLDocument did not extend the Document interface in some versions
// of Mozilla. Extend both!
XMLDocument.prototype.loadXML =

Document.prototype.loadXML = function (s)
{
// parse the string to a new doc
var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
// remove all initial children
while (this.hasChildNodes())
this.removeChild(this.lastChild);
// insert and import nodes

for (var i = 0; i < doc2.childNodes.length; i++)
{
this.appendChild(this.importNode(doc2.childNodes[i], true));
}
};

/**//*
* xml getter
*
* This serializes the DOM tree to an XML String
*
* Usage: var sXml = oNode.xml
*
*/
// XMLDocument did not extend the Document interface in some versions
// of Mozilla. Extend both!

XMLDocument.prototype.__defineGetter__("xml", function ()
{
return (new XMLSerializer()).serializeToString(this);
});

Document.prototype.__defineGetter__("xml", function ()
{
return (new XMLSerializer()).serializeToString(this);
});
}
在上面的getXmlHttpPrefix()方法中,我们发现["MSXML2", "Microsoft", "MSXML", "MSXML3"];所指定的4个前缀,在创建IE浏览器支持的XHR对象时,提供了不同的创建方法。但如果要在代码中,换一种方式来写,应该如何写呢?这几种前缀+".XMLHttp"所创建的对象分别有什么区别呢?所以在网上查了一下,关于这方面的内容还蛮多,特将部分内容记录:
片断1:

Code

/**//*****************************************************************************************
Object CreateHTTPPoster(void)
创建尽可能高版本的XMLHTTP对象
*****************************************************************************************/

function CreateHTTPPoster()
{
if(window.XMLHttpRequest) return new XMLHttpRequest();

try
{
return new ActiveXObject('MSXML2.XMLHTTP.4.0');

}catch(e)
{try
{
return new ActiveXObject('MSXML2.XMLHTTP.3.0');

}catch(e)
{try
{
return new ActiveXObject('MSXML2.XMLHTTP.2.6');

}catch(e)
{try
{
return new ActiveXObject('MSXML2.XMLHTTP');

}catch(e)
{try
{
return new ActiveXObject('Microsoft.XMLHTTP');

}catch(e)
{return null;}}}}}
}

片断2:

Code
function CreateHTTP()

{
if (window.XMLHttpRequest) return(new XMLHttpRequest());
var arr_t = new Array
(
"MSXML2.XMLHTTP.4.0",
"MSXML2.XMLHTTP.3.0",
"MSXML2.XMLHTTP.2.6",
"Microsoft.XMLHTTP",
"MSXML.XMLHTTP"
);
for (var i=0; i<arr_t.length; i++)

{
try

{
return(new ActiveXObject(arr_t[i]));
}
catch(e)

{
}
}
return(null);
}

上面两个代码基本写法类似,都是通过调用较高版本的XMLHTTP对象,按顺序创建较高版本的XMLHTTP对象。在我们使用XMLHTTP时,要优先使用较高版本的XHR对象,现在已经升级到5.0版本了new ActiveXObject("Msxml2.XMLHTTP.5.0")。
至于究竟这些不同版本的XMLHTTP对象有何区别,我们可以参考以下文章:
http://eric-2007.javaeye.com/blog/338731