天天看点

Ajax程序与IE7不兼容的问题

   原文地址

http://bbs.netpu.net/viewthread.php?tid=3138

问题提出

    用JSP+XAjax实现了一个功能简单的小页面。不曾想这个页面在Firfox中测试一直很正常,到IE7下测试则时而正常,时而出错。打开XAjax的Debug功能,也没能获取有价值的信息,非常郁闷。

    于是使用Ajax+IE7作为关键字,到搜索引擎中去搜索,找到很多关于Ajax代码在IE7下运行出错的帖子,但都是有人发问无人回答,看来只好自己去解决啦。

解决思路

    既然这个页面在Firefox和IE6上都运行正常,那么我们来看看Firefox与IE6、IE7在处理Ajax代码时都有哪些区别吧?

    我们知道,Ajax 应用程序的核心是XMLHttpRequest,但是由于不同浏览器的兼容问题,创建这个对象的方法是有很大的区别的。

    在Mozilla、Firefox、Safari、Opera等浏览器上,使用下边的语句创建XMLHttpRequest:

CODE:   [Copy to clipboard]     var xmlHttp = new XMLHttpRequest();

而在IE6及以下版本,则使用以下语句创建XMLHttpRequest:

CODE:   [Copy to clipboard]     xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); 或

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

那IE7又与IE6有些什么区别呢?

    在MSDN上:About Native XMLHTTP一文中里边有这样的说明:

    http://msdn2.microsoft.com/en-us/library/ms537505.aspx

    In Internet Explorer 6 and earlier, XMLHTTP was implemented as an ActiveX object provided by Microsoft XML (MSXML). Beginning with Internet Explorer 7, XMLHTTP is also exposed as a native scripting object.

    也就是说IE7增加了Native XMLHTTP支持。

    同时里边给了一段示例代码:

CODE:   [Copy to clipboard]     var xmlHttp = null;

    if (window.XMLHttpRequest) {

      // If IE7, Mozilla, Safari, and so on: Use native object.

      xmlHttp = new XMLHttpRequest();

    }

    else

    {

      if (window.ActiveXObject) {

         // ...otherwise, use the ActiveX control for IE5.x and IE6.

         xmlHttp = new ActiveXObject('MSXML2.XMLHTTP.3.0');

      }

    }

由此可以看出,IE7比IE6多了Native XMLHTTP支持。那么会不会是这个Native XMLHTTP导致的问题呢?不用这个Native XMLHTTP会怎么样?还好IE7的设计者也考虑了这一点,IE7提供了两个功能:

    一个是通过设置来禁用“Native XMLHTTP支持”(默认是打开)。

Ajax程序与IE7不兼容的问题

    挑掉Enable Native XMLHTTP support上的勾就可以禁用它了。

    另外一个功能就是兼容IE6创建XMLHttpRequest的方法。

解决方法

    OK,既然这样,我们禁用“Native XMLHTTP支持”,看看我们的程序是否正常了?

    测试结果,我们的程序一切正常。

    但是等等,我们总不能要求用户访问我们的页面之前禁用“Native XMLHTTP支持”吧?汗一下!

    于是我们只能在Ajax的XMLHttpRequest创建代码上想办法了。

    想什么办法呢?说实话,对Ajax我是超级外行,没办法,硬着头皮来吧。既然问题出在创建XMLHttpRequest对象上,那么我们就从这里下手吧。

    网上很多文章都强调,为了跨浏览器兼容,首先检查是否支持Native XMLHTTP。

    比如这篇文章:Ajax on IE 7: Check native first

    http://ajaxian.com/archives/ajax-on-ie-7-check-native-first

    还有前文提到的IE7创建XMLHttpRequest的示例代码,也是先检查是否支持Native XMLHTTP的。看看我们用的XAjax是咋创建对象的吧。

CODE:   [Copy to clipboard]    

    if ("undefined" != typeof XMLHttpRequest) {

        xajax.tools.getRequestObject = function() {

                return new XMLHttpRequest();

        }

    } else if ("undefined" != typeof ActiveXObject) {

        xajax.tools.getRequestObject = function() {

                try {

                        return new ActiveXObject("Msxml2.XMLHTTP.4.0");

                } catch (e) {

                        xajax.tools.getRequestObject = function() {

                                try {

                                        return new ActiveXObject("Msxml2.XMLHTTP");

                                } catch (e2) {

                                        xajax.tools.getRequestObject = function() {

                                                return new ActiveXObject("Microsoft.XMLHTTP");

                                        }

                                        return xajax.tools.getRequestObject();

                                }

                        }

                        return xajax.tools.getRequestObject();

                }

        }

    } else if (window.createRequest) {

        xajax.tools.getRequestObject = function() {

                return window.createRequest();

        }

    } else {

        xajax.tools.getRequestObject = function() {

                throw { name: 'GetRequestObject', message: 'XMLHttpRequest is not available, xajax is disabled' }

        }

    }

果然不出我们预料,也是先检查是否支持Native XMLHTTP的。这样一来一旦使用的是IE7,那么IE7的Native XMLHTTP会被启用,我们的程序就会出错啦。

    换个策略,我们如果先检查ActiveX object对象呢?说做就做,我们修改了这部分代码(简单地说就是调换了一下顺序),测试,一切正常,Firefox、IE6、IE7都正常(抱歉我手头只有这几个浏览器。

    至此大功告成!修改后的代码:

    //创建xmlHttp对象

    var xmlHttp = false;    

    if("undefined" != typeof ActiveXObject){

     try{

      xmlHttp = new ActiveXObject("Msxml2.XMLHTTP.4.0");

     } catch(e){

      try{

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

      } catch(e2){

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

      } 

     }

    }else if("undefined" != typeof XMLHttpRequest){

     xmlHttp = new XMLHttpRequest();

    }else if (window.createRequest) {

     xmlHttp = window.createRequest();

    }

总结一下

    也许是XAjax对IE7的Native XMLHTTP支持不好,也许是我们对XAjax的使用有问题,也许真的是IE7的Native XMLHTTP有BUG,不管怎么说,我们换一个角度换一个方法解决了这个问题,也加深了我们对Ajax技术的理解。至于XAjax或者IE7何时解决这 个问题,我们拭目以待!

继续阅读