AJAX: отправка запросов xmlhttp в цикле

У меня есть эта функция ниже, и я вызываю эту функцию в цикле. Я получаю предупреждение n раз, но только n-1 или иногда n-2 ответы

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

Я создал класс (который вы можете легко изменить) для вызова функции в цикле, и он правильно вызывает функции. Возможно, это может быть применимо к вашей потребности.

(Также, если кто-то видит что-то неправильно, хорошо слышать от других)

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> 

и getresponse.php

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

onreadystatechange прекращается, когда ваша функция заканчивается, потому что объект xmlhttp удаляется, поскольку это не глобальная переменная. Я прав?

Лучше было бы поместить только запрос AJAX в функцию, так что объект xmlhttp будет создан только один раз (я использовал более короткую версию для создания объекта xmlhttp в этом примере).

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

Как правило, это должно работать, но нам нужна дополнительная информация о том, как вы на самом деле запускаете этот цикл, чтобы узнать, что может быть неправильным.

Я также добавил encodeURIComponent и изменил условие внутри функции обратного вызова, потому что status не всегда 200 когда readyState достигает 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(); }