zoukankan      html  css  js  c++  java
  • xmlHttp请求在IE6/IE7/Firefox中只成功执行一次之分析

            异步调用的问题是五花八门,说碰上就碰上,这次我遇到的麻烦就是这样,同样的异步请求,在IE6SP1中运行一点问题没有,在IE6SP2中只成功执行一次后,每次的结果都和第一次一样,随后又尝试IE7和Firefox,效果和IE6SP2一样,用Fiddler监视明明显示正确的请求和返回值,可就是最终执行的效果一点都没变化,相当郁闷。这样的结果自然就想到了肯定是缓存在作怪,但始终还是要查明到底是哪段代码引起缓存的,我把关注的焦点放在如下代码:
    var xmlHttp = null;
    function getXmlHttp(){
        if(window.XMLHttpRequest){
            xmlHttp = new XMLHttpRequest();
        }else if(window.ActiveXObject){
            var arrXmlHttpTypes = ['MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.3.0','Microsoft.XMLHTTP'];
            for(var i=0;i<arrXmlHttpTypes.length;i++){
                try{
                    xmlHttp = new ActiveXObject(arrXmlHttpTypes[i]);
                }catch(ex){}
            }
        }
    }

    function getXmlDom(content){
        var _xmlDom = null;
        if (!window.DOMParser  && window.ActiveXObject){
            var arrXmlDomTypes = ['MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','Microsoft.XMLDOM'];
            for(var i=0;i<arrXmlDomTypes.length;i++){
                try{
                    _xmlDom = new ActiveXObject(arrXmlDomTypes[i]);
                    _xmlDom.async = false;
                    _xmlDom.loadXML(content);
    //                _xmlDom.setProperty('SelectionLanguage', 'XPath');
                }catch(ex){}
            }
        }else{
                try{
                    var domParser = new window.DOMParser();
                    _xmlDom =  domParser.parseFromString(content, 'text/xml');
                    Element.prototype.selectSingleNode=function(sXPath){
                        var oEvaluator = new XPathEvaluator();
                        var oResult = oEvaluator.evaluate(sXPath,this,null, XPathResult.FIRST_ORDERED_NODE_TYPE,null);
                        if(null != oResult){
                            return oResult.singleNodeValue;
                        }
                        return null;
                    }
                   
                    Element.prototype.selectNodes = function(sXPath){
                        var oEvaluator = new XPathEvaluator();
                        var oResult = oEvaluator.evaluate(sXPath,this,null, XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);
                        var aNodes = new Array();
                        if(null != oResult){
                            var oElement = oResult.iterateNext();
                            while(oElement){
                                aNodes.push(oElement);
                                oElement = oResult.iterateNext();
                            }
                        }
                        return aNodes;
                    }
                   
                    Element.prototype.__defineGetter__("text",function(){ return this.textContent; });        }
            catch (ex)
            {
               
            }
        }
        return _xmlDom;
    }              

    function postRequest(url,parameters,callBack){
        if(xmlHttp !=null){
            xmlHttp.onreadystatechange = function(){
                if(xmlHttp.readyState == 4){
                    if(xmlHttp.status == 200){
                        xmlDom = getXmlDom(xmlHttp.responseText);
                        if(xmlDom != null){
                            eval(callBack(xmlDom));
                        }
                    }
                }
            }
            xmlHttp.open('Post',url,true);
            xmlHttp.setRequestHeader("Content-Length",parameters.length);
            xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            xmlHttp.send(parameters);
        }
    }
    getXmlHttp();

            仔细一看红色标注的代码,可不是这里有问题么,用了全局的xmlHttp对象,这一定就是缓存的根本原因了,也怪一开始自己太不认真了,写这么懒的代码。赶紧改一下.

    function getXmlHttp(){
        
    var _xmlHttp = null;
        
    if(window.XMLHttpRequest){
            _xmlHttp 
    = new XMLHttpRequest();
            
    return _xmlHttp;
        }
    else if(window.ActiveXObject){
            
    var arrXmlHttpTypes = ['MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.3.0','Microsoft.XMLHTTP'];
            
    for(var i=0;i<arrXmlHttpTypes.length;i++){
                
    try{
                    _xmlHttp 
    = new ActiveXObject(arrXmlHttpTypes[i]);
                    
    return _xmlHttp;
                }
    catch(ex){}
            }
        }
    }

    function getXmlDom(content){
        
    var _xmlDom = null;
        
    if (!window.DOMParser  && window.ActiveXObject){
            
    var arrXmlDomTypes = ['MSXML2.DOMDocument.6.0','MSXML2.DOMDocument.3.0','Microsoft.XMLDOM'];
            
    for(var i=0;i<arrXmlDomTypes.length;i++){
                
    try{
                    _xmlDom 
    = new ActiveXObject(arrXmlDomTypes[i]);
                    _xmlDom.async 
    = false;
                    _xmlDom.loadXML(content);
    //                _xmlDom.setProperty('SelectionLanguage', 'XPath');
                }catch(ex){}
            }
        }
    else
            try{
                    var domParser = new window.DOMParser();
                    _xmlDom 
    =  domParser.parseFromString(content, 'text/xml');
                    Element.prototype.selectSingleNode
    =function(sXPath){
                        
    var oEvaluator = new XPathEvaluator();
                        
    var oResult = oEvaluator.evaluate(sXPath,this,null, XPathResult.FIRST_ORDERED_NODE_TYPE,null);
                        
    if(null != oResult){
                            
    return oResult.singleNodeValue;
                        }
                        
    return null;
                    }
                    
                    Element.prototype.selectNodes 
    = function(sXPath){
                        
    var oEvaluator = new XPathEvaluator();
                        
    var oResult = oEvaluator.evaluate(sXPath,this,null, XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);
                        
    var aNodes = new Array();
                        
    if(null != oResult){
                            
    var oElement = oResult.iterateNext();
                            
    while(oElement){
                                aNodes.push(oElement);
                                oElement 
    = oResult.iterateNext();
                            }
                        }
                        
    return aNodes;
                    }
                    
                    Element.prototype.__defineGetter__(
    "text",function(){ return this.textContent; });
            }
            
    catch (ex) 
            {
                
            }
        }
        
    return _xmlDom;
    }               

    function postRequest(url,parameters,callBack){
        
    var xmlHttp = getXmlHttp();
        
    if(xmlHttp !=null){
            xmlHttp.onreadystatechange 
    = function(){
                
    if(xmlHttp.readyState == 4){
                    
    if(xmlHttp.status == 200){
                        xmlDom 
    = getXmlDom(xmlHttp.responseText);
                        
    if(xmlDom != null){
                            eval(func(xmlDom));
                        }
                    }
                }
            }
            xmlHttp.open(
    'Post',url,true);
            xmlHttp.setRequestHeader(
    "Content-Length",parameters.length);
            xmlHttp.setRequestHeader(
    "Content-Type","appli也cation/x-www-form-urlencoded");
            xmlHttp.send(parameters);
        }
    }
            最后在网上也搜索了一下关于这个问题的解决办法,有不少文章介绍了另一种办法,就是对异步调用的参数加上一个随机数,我想,这个办法也太不厚道了吧,另外有一点值得借鉴的就是使用JSON实例化xmlHttp,将属性和方法用键值对形式完全包装,从可读性和扩展性上说,绝对是个好主意。以后我也经常写写这样的例子。先放legend的版本如下,摘自(http://www.ugia.cn/?p=85),带对象池的封装:
    /**
     * XMLHttpRequest Object Pool
     *
     * @author    legend <legendsky@hotmail.com>
     * @link      http://www.ugia.cn/?p=85
     * @Copyright www.ugia.cn
     
    */ 

    var XMLHttp = {
        _objPool: [],

        _getInstance: 
    function ()
        {
            
    for (var i = 0; i < this._objPool.length; i ++)
            {
                
    if (this._objPool[i].readyState == 0 || this._objPool[i].readyState == 4)
                {
                    
    return this._objPool[i];
                }
            }

            
    // IE5中不支持push方法
            this._objPool[this._objPool.length] = this._createObj();

            
    return this._objPool[this._objPool.length - 1];
        },

        _createObj: 
    function ()
        {
            
    if (window.XMLHttpRequest)
            {
                
    var objXMLHttp = new XMLHttpRequest();

            }
            
    else
            {
                
    var MSXML = ['MSXML2.XMLHTTP.5.0''MSXML2.XMLHTTP.4.0''MSXML2.XMLHTTP.3.0''MSXML2.XMLHTTP''Microsoft.XMLHTTP'];
                
    for(var n = 0; n < MSXML.length; n ++)
                {
                    
    try
                    {
                        
    var objXMLHttp = new ActiveXObject(MSXML[n]);
                        
    break;
                    }
                    
    catch(e)
                    {
                    }
                }
             }          

            
    // mozilla某些版本没有readyState属性
            if (objXMLHttp.readyState == null)
            {
                objXMLHttp.readyState 
    = 0;

                objXMLHttp.addEventListener(
    "load"function ()
                    {
                        objXMLHttp.readyState 
    = 4;

                        
    if (typeof objXMLHttp.onreadystatechange == "function")
                        {
                            objXMLHttp.onreadystatechange();
                        }
                    },  
    false);
            }

            
    return objXMLHttp;
        },

        
    // 发送请求(方法[post,get], 地址, 数据, 回调函数)
        sendReq: function (method, url, data, callback)
        {
            
    var objXMLHttp = this._getInstance();

            
    with(objXMLHttp)
            {
                
    try
                {
                    
    // 加随机数防止缓存
                    if (url.indexOf("?"> 0)
                    {
                        url 
    += "&randnum=" + Math.random();
                    }
                    
    else
                    {
                        url 
    += "?randnum=" + Math.random();
                    }

                    open(method, url, 
    true);

                    
    // 设定请求编码方式
                    setRequestHeader('Content-Type''application/x-www-form-urlencoded; charset=UTF-8');
                    send(data);
                    onreadystatechange 
    = function ()
                    {
                        
    if (objXMLHttp.readyState == 4 && (objXMLHttp.status == 200 || objXMLHttp.status == 304))
                        {
                            callback(objXMLHttp);
                        }
                    }
                }
                
    catch(e)
                {
                    alert(e);
                }
            }
        }
    };  
  • 相关阅读:
    Eclipse Alt + / 快捷键失效
    oracle nvl()函数
    搭建spring boot项目
    Maximum call stack size exceeded
    vue混入函数问题
    ASP.NET Core 2.0中的Azure Blob存储
    如何在ASP.NET Core 2.0中使用Razor页面
    将参数传递给ASP.NET Core 2.0中的中间件
    使用.net core在Ubuntu构建一个TCP服务器
    如何在ASP.NET Core Web API测试中使用Postman
  • 原文地址:https://www.cnblogs.com/BeanHsiang/p/1107131.html
Copyright © 2011-2022 走看看