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);
            }
        }
    }
};  

转载于:https://www.cnblogs.com/BeanHsiang/archive/2008/03/15/1107131.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值