ActiveX不可用时,你的AJAX会出错么?

      最近遇到一个问题,ie6下js可用,但用AJAX做异步请求的时候总是失败,用的是jQuey封装的,报的错误是: Error:Automation 服务器不能创建对象 。查找后发现原来是客户将Internet选项里的安全设置过高,将“对标记为可安全执行的ActiveX控件执行脚本“设置为禁用造成的。

      先来看下jQuery中关于创建XHR对象的代码:

jQuery.js

var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();

 此时的 typeof window.ActiveXObject会返回一个function ,但new ActiveXObject("Microsoft.XMLHTTP")时就会产生上面的异常,问题到此基本知道原因了,本着举一反三的精神,找了下其他js框架创建XHR对象的方法



prototype.js

var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new XMLHttpRequest()},
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
  },
  activeRequestCount: 0
};

 

mootools.js

Browser.Request = function(){
    return $try(function(){
        return new XMLHttpRequest();
    }, function(){
        return new ActiveXObject('MSXML2.XMLHTTP');
    });
};
 


dojo.js

  d._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
    d._xhrObj = function(){
            // summary:
            //        does the work of portably generating a new XMLHTTPRequest
            //        object.
            var http = null;
            var last_e = null;
            if(!dojo.isIE || !dojo.config.ieForceActiveXXhr
){
                try{ http = new XMLHttpRequest(); }catch(e){}
            }
            if(!http){
                for(var i=0; i<3; ++i){
                    var progid = d._XMLHTTP_PROGIDS[i];
                    try{
                        http = new ActiveXObject(progid);
                    }catch(e){
                        last_e = e;
                    }
                    if(http){
                        d._XMLHTTP_PROGIDS = [progid];  // so faster next time
                        break;
                    }
                }
            }
            if(!http){
                throw new Error("XMLHTTP not available: "+last_e);
            }
            return http; // XMLHTTPRequest instance
        }

 关于 dojo.config.ieForceActiveXXhr

 

        //Workaround to get local file loads of dojo to work on IE 7
        //by forcing to not use native xhr.
        if(dojo.isIE && window.location.protocol 
=== "file:"){
            dojo.config.ieForceActiveXXhr=true;
        }

    关于window.location.protocol

 

  The URL protocol section including the colon after the protocol name.
        The values are normally http: or file:. The following JavaScript code
        may be used to identify the source of the URL.
        switch (window.location.protocol)
                {
                   case "http:":
                      document.write("From Web<BR>\n")
                      break
                   case "file:":
                      document.write("From Local computer<BR>\n")
                      break
                   default:
                      document.write("Unknown Source<BR>\n")
                      break
                }

    这里需要解释下,从ie7开始加入了对原生的XMLHttpRequest的支持,即ie7以后的版本中对于XHR对象的创建即可以通过ActiveXObject也可以通过直接的new XMLHttpRequest()实现,但是出于安全考虑, ie7的原生XHR是不支持本地使用的,所以在这段js中如果检测但浏览器版本是ie7并且是本地请求创建XHR对象则还是用ActiveXObject来实现的。

(这个细节就是体现js框架差距的地方吧 O(∩_∩)O)
       
YUI:

connection.js
/*
_msxml_progid:[
        'Microsoft.XMLHTTP',
        'MSXML2.XMLHTTP.3.0',
        'MSXML2.XMLHTTP'
        ]

*/
createXhrObject:function(transactionId)
    {
        var obj,http;
        try
        {
            // Instantiates XMLHttpRequest in non-IE browsers and assigns to http.
            http = new XMLHttpRequest();
            //  Object literal with http and tId properties
            obj = { conn:http, tId:transactionId };
            YAHOO.log('XHR object created for transaction ' + transactionId, 'info', 'Connection');
        }
        catch(e)
        {
            for(var i=0; i<this._msxml_progid.length; ++i){
                try
                {
                    // Instantiates XMLHttpRequest for IE and assign to http
                    http = new ActiveXObject(this._msxml_progid[i]);
                    //  Object literal with conn and tId properties
                    obj = { conn:http, tId:transactionId };
                    YAHOO.log('ActiveX XHR object created for transaction ' + transactionId, 'info', 'Connection');
                    break;
                }
                catch(e2){}
            }
        }
        finally
        {
            return obj;
        }
    }

  关于{'Microsoft.XMLHTTP','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Msxml2.XMLHTTP.4.0' ...}这些proGid的区别以及为什么框架们要一遍一遍的去尝试的意义请参考

 

 Difference between MSXML2.XmlHttp and Microsoft.XmlHttp ProgIDs

  (微软真的害人啊 )


   对比这5个主流的框架可以从代码风格上看出点东西:

     1)jQuery受欢迎是有道理的:能一行代码搞定的东西,用起来学起来都方便,即使偶然极端情况下会出错,可我们的原则就是花最少精力去解决大部分的问题,剩下的一小部分问题,交给那20%倒霉的程序员吧。

     2)相互借鉴,发扬光大,站在巨人的肩膀上...都很适合开源的。

     3)想做大做强就必须有条条框框的束缚。(所以还是喜欢jquery的简单)

     3) Dojo应该是最开发者体验的框架了,甚至读它的源码能扩展一连串的知识,佩服ing,在fireBug控制台下看dojo的类库唰唰的加载多好玩啊:-D

   附件是对于上述几个框架的AJAX简单测试的demo,带各个框架的源码,可当个简易教程,并附加DojoToolbox.air

   方便想了解的的同学们~~O(∩_∩)O

你可能感兴趣的:(jquery,Ajax,框架,Microsoft,dojo)