开发者

AJAX: sending xmlhttp requests in a loop

I have this function below and I call that function in a loop I get the 开发者_C百科alert n times but only n-1 or sometimes n-2 responses

if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
    if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
        alert(xmlhttp.responseText);
        //document.getElementById("warnings_panel").innerHTML+=xmlhttp.responseText;
    }
}

alert("in ajax) 

xmlhttp.open("GET","getresponse.php?start="+ start + "&end=" + end,true);
xmlhttp.send();


I have made a class (that you can modify easily) for calling a function in loop and it calls the functions correctly. Maybe this could apply to your need.

(Also if anyone sees something wrong it's good to hear from others)

test.htm

<html>
<head>
<script type="text/javascript">
function myXmlHttp() { 

    /*constructor simulator*/ 
    this.setPersitent=
    function (file, onReadyFunc,params,loop) 
    {  
        myXmlHttpObj.loop = loop;  
        myXmlHttpObj.file=file;
        myXmlHttpObj.onReadyFunc='myXmlHttpObj.'+onReadyFunc;
        myXmlHttpObj.params=params;  
        myXmlHttpObj.mySetRequest();    
    }
    this.setParams=
    function ( params ) 
    {   
        myXmlHttpObj.params=params;  
    }

    <!--Standard initial code-->
    this.mySetRequest =
    function  ()
    {
        request = false;
        try { request = new XMLHttpRequest(); } 
        catch (trymicrosoft) {
            try { request = new ActiveXObject("Msxml2.XMLHTTP"); } 
            catch (othermicrosoft) {
                try {request = new ActiveXObject("Microsoft.XMLHTTP");} 
                catch (failed) {request = false;}/*catch3*/}/*catch2*/}/*catch1*/
        if (!request) 
        alert("Error initializing XMLHttpRequest!"); 
    }  /*func*/ 

    this.mySendReq=
    function() 
    { 
        var url = myXmlHttpObj.file;   
        request.open("POST", url, true);  
        //Some http headers must be set along with any POST request.
        request.setRequestHeader
        ("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
        request.setRequestHeader("Content-length", myXmlHttpObj.params.length);
        request.setRequestHeader("Connection", "close"); 
        request.onreadystatechange = eval(myXmlHttpObj.onReadyFunc);  
        request.send(myXmlHttpObj.params);  
    } 

    this.listenPHP = 
   function  ( ) {    
     if ( request.readyState == 4) {
       if ( request.status == 200) 
       {   
            alert(request.responseText);
            myXmlHttpObj.loop--;
            if(myXmlHttpObj.loop>0)
            { 
                myXmlHttpObj.setParams("js_rand="+Math.random()+"");
                myXmlHttpObj.mySendReq();  
            }

        }//inner if 
       else{alert("status is " + request.status);}
     }//outer iff
   }//function  

}//END 

myXmlHttpObj = new myXmlHttp();
myXmlHttpObj.setPersitent
('getresponse.php', 'listenPHP',"js_rand="+Math.random()+"",3)  ;

myXmlHttpObj.mySendReq();  

</script>
</head>
<body >

</body>
</html>

and getresponse.php

<?PHP
echo 'I recived this random from js:',$_POST['js_rand'],'
 this rand is from php:',rand(1,9999);
?>


onreadystatechange gets terminated when your function ends because the xmlhttp object gets removed as it is not a global variable. Am I right?

Better would be to put only the AJAX request in a function, so that the xmlhttp object is only created once (I used a shorter version to create the xmlhttp object in this example).

var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');

function request() {
    xmlhttp.open('GET', 'getresponse.php?start=' + start + '&end=' + end, true);
    xmlhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            alert(xmlhttp.responseText);
        }
    }
    xmlhttp.send(null);
}


Generally, this should work, but we need more information about how you actually run that loop to know what might be wrong.

I also added encodeURIComponent and changed the condition inside the callback function, because status isn't always 200 when readyState reaches 4.

function request(start, end) {
    var xmlhttp;

    if (window.XMLHttpRequest)
        xmlhttp = new XMLHttpRequest();
    else
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

    xmlhttp.open('GET', 'getresponse.php?start=' + encodeURIComponent(start) + '&end=' + encodeURIComponent(end), true);
    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4)
            if (xmlhttp.status == 200) {
                alert(xmlhttp.responseText);
            } else {
                // status ≠ 200, output useful error message
            }
    };
    xmlhttp.send();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜