这两天闲着没事,看了一些自己以前写的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