zoukankan      html  css  js  c++  java
  • 关于IE下AJAX的问题探讨

    今天JS练手的时候,想封装一个发送AJAX请求的对象,当然,是想要兼容全浏览器的。代码如下:

    var Ajax = { 
    xhr: null, 
    callback: null, 
    XMLHttp: function() { 
    var xmlhttp; 
    //标准浏览器 
    if(window.XMLHttpRequest) { 
    try { 
    xmlhttp = new XMLHttpRequest(); 
    } 
    catch(e) { 
    alert('Unknown Ajax Error'); 
    //console.log('Unknown Ajax Error'); 
    } 
    } 
    //IE浏览器 
    else { 
    if(window.ActiveXObject) { 
    try { 
    xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); 
    } 
    catch(e) { 
    try { 
    xmlhttp = new ActiveXObject('MSXML2.XMLHTTP'); 
    } 
    catch(e) { 
    alert('Unknown Ajax Error'); 
    //console.log('Unknown Ajax Error'); 
    } 
    } 
    } 
    } 
    return xmlhttp; 
    }, 
    connect: function(paramsObj) { 
    var PO = paramsObj; 
    //判断传参合法性 
    if(!(PO instanceof Object)) { 
    alert('Ajax params illegal'); 
    //console.log('Ajax params illegal'); 
    return false; 
    } 
    else if(!(PO.url&&PO.method&&PO.callback)) { 
    return false; 
    } 
    //初始化内部参数 
    this.xhr = this.XMLHttp(); 
    this.callback = PO.callback; 
    //遍历params对象并生成url参数 
    var requestParams = ''; 
    if(PO.params) { 
    for(key in Po.params) { 
    requestParams += '&' + key + '=' + params[key]; 
    } 
    requestParams = requestParams.substr(1); 
    } 
    //发起Ajax请求 
    try { 
    var xhr = this.xhr; 
    xhr.onreadystatechange = this.response; 
    //POST请求处理 
    if(PO.method.toLowerCase()=='post') { 
    xhr.open('POST',PO.url,true); 
    xhr.send(requestParams); 
    } 
    //GET请求处理 
    else if(PO.method.toLowerCase()=='get') { 
    xhr.open('GET',PO.url+'?'+requestParams,true); 
    xhr.send(null); 
    } 
    } 
    catch(e) { 
    this.callback(null,-1); 
    } 
    }, 
    response: function() { 
    // 此段代码在全浏览器下测试通过 
    // if(Ajax.xhr.readyState==4) { 
    // if(Ajax.xhr.status=='200') { 
    // Ajax.callback(Ajax.xhr.responseText); 
    // } 
    // else { 
    // Ajax.callback(null,Ajax.xhr.status); 
    // } 
    // } 
    // 
    // 下面的代码在IE下失效(无报错,请求有相应,却没有返回结果),其它浏览器无此问题 
    if(this.readyState==4) { 
    if(this.status=='200') { 
    Ajax.callback(this.responseText); 
    } 
    else { 
    Ajax.callback(null,this.status); 
    } 
    } 
    } 
    }; 
    
    //Ajax实例 
    Ajax.connect({ 
    url: 'test.html', 
    method: 'GET', 
    callback: function(data,err) { 
    if(data!=null) { 
    alert(data); 
    // console.log(data); 
    } 
    else { 
    alert(err); 
    // console.log(err); 
    } 
    } 
    }); 

    问题描述: 大家看一下我代码中有一块注释掉的代码,那块代码是在全浏览器下测试通过的。而没有注释掉的代码是有问题的代码,具体表现: 

    在Chrome,Firefox,Opera,Safari下测试通过,在IE6、7(IE8+没有测试)下的表现是:没有报错,也没有返回结果。 

    对比上下两块代码的不同,我想有两个可能,一个是this指向的问题,一个是IE下onreadystatechange函数执行的上下文环境有区别于其它浏览器。但是现在又无法确定问题,IE6、7下的JS调试又挺困难的(试了firebug-lite,但是没有想象中的好用,而且这个Ajax对象在firebug-lite下调用却成功了,有点糊涂) 
    解决过程: 

    其实测试方法很简单。主要是头脑一发热没想到,吃了个饭回来就恍然大悟。 

    其实JS在处理this指向不明的问题的时候,可以尝试使用this instanceof Object这类判断去了解它指向的是一个什么类型的变量。而对于判断是否为全局调用,则可以使用this===window。在这里我用的就是这个方法。 

    在代码出现问题的那一块,我们可以试着插入一段: 

    alert(this instanceof Object); 

    结果发现,在IE6下,返回为false!一目了然!在IE下才可能出现如此诡异的返回值!证明什么?也就是说函数的执行上下文并非是对象!如此一来,在IE下就只能想到window对象了,要知道IE向来都是奇葩。你们标准浏览器说window对象是对象,我就偏不认。你还在怀疑我的看法?那何不试试? 

    alert(this===window); 

    结果是true!怎么样?没话说了吧?所以这样,问题就明朗了: 

    在IE下,AJAX请求得到响应后,回调函数onreadystatechange是在全局环境下被调用的。而在标准浏览器下,其执行上下文是XMLHttpRequest对象。故造成了我这次的“事故”。

  • 相关阅读:
    vs里替换的正则表达式引用
    javascript学习
    filter用法(使静态页面和js通过iis的asp.net过滤器)
    表格的交替选择行【jquery中siblings的用法】
    表格的cell固定宽度,当内容达到宽度时换行
    collection模块(具名元组、队列、有序字典、默认值字典)、time 模块、随机模块:random、os模块、sys模块、序列化模块
    继承的用法、属性的查找顺序、组合、新式类与经典类、菱形继承等
    多态、以及常用的关于类的方法(isinstance、issubclass、slots等)运算符重载的实现、上下文管理等
    封装、prorerty装饰器、python实现封装的原理等
    面向对象、类和对象、__dict__方法、__init__方法、对象绑定方法、类绑定方法、对象交互
  • 原文地址:https://www.cnblogs.com/ranran/p/3725146.html
Copyright © 2011-2022 走看看