在Ajax应用中创建万能的XmlHttpRequest对象

引自http://www.cnblogs.com/xionglee/articles/1499209.html

通常,在我的ASP.NET程序中,我通常这样创建XHR对象:


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对象的扩展,其内容为:

//<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:


/*****************************************************************************************   
  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:


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

posted @ 2012-04-28 20:45  积淀  阅读(172)  评论(0编辑  收藏  举报