Ajax повторно отправляет XMLHttpRequest

У меня есть скрипт js/ajax на стороне клиента:

<p>server  time  is:  <strong  id="stime">Please  wait...</strong></p>

<script>
function  updateAjax()  {
    xmlhttp  =  new  XMLHttpRequest();
    xmlhttp.onreadystatechange  =  function()  {
        if (xmlhttp.readyState==3  &&  xmlhttp.status==200)  {
            document.getElementById("stime").innerHTML=
            xmlhttp.responseText;
        }
        if  (xmlhttp.readyState==4)  {  
            xmlhttp.open("GET","date-sleep.php",true);
            xmlhttp.send();
        }
    }
    xmlhttp.open("GET","date-sleep.php",true);  
    xmlhttp.send();
}
window.setTimeout("updateAjax();",100);
</script>

И на стороне сервера:

<?php
    echo  6;
    for  ($i=0;  $i<10;  $i++)  {
        echo  $i;
        ob_flush();  flush();
        sleep(1);
    }
?>

После первого «открытия» и «отправки» он работает нормально, но когда сервер заканчивает скрипт и xmlhttp.readyState == 4, xmlhttp повторно отправляет запрос, но ничего не происходит.


person jllj    schedule 03.06.2012    source источник


Ответы (1)


Вместо того, чтобы все время повторно использовать один и тот же объект XHR, попробуйте повторить функцию с новым объектом. Это должно по крайней мере исправить проблемы несовместимости, как вы указали.

Попробуйте повторно вызвать свою функцию Ajax внутри ее обратного вызова, если вы хотите зацикливать ее бесконечно.

if  (xmlhttp.readyState==4) {  
     updateAjax(); //or setTimeout("updateAjax();",100); if you want a delay
}

Я также предлагаю поместить ваш метод .innerHTML в .readyState==4, когда запрошенный документ полностью загружен, и .status==200 что означает успех. Как это:

if (xmlhttp.readyState==4  &&  xmlhttp.status==200) {
       document.getElementById("stime").innerHTML=
       xmlhttp.responseText;
       updateAjax(); //or setTimeout("updateAjax();",100);
}

Кроме того, если вы хотите, чтобы ваш Ajax был кроссбраузерным, вам следует проверить, поддерживает ли браузер объект XHR который вы используете:

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

Я только что набрал код выше, но он должен работать нормально, чтобы добавить совместимость со старыми версиями IE и другими браузерами.

person Fabrício Matté    schedule 03.06.2012
comment
Я выяснил, что это работает в Iceweasel. Я предполагаю, что это не работает должным образом из-за некоторого кэширования Firefox. Изменение innerHTML в этом блоке if изменит поведение скрипта, который должен обновлять страницу всегда после отправки сервером следующих данных, а не только при закрытии соединения. - person jllj; 04.06.2012
comment
Мое вышеприведенное решение является кросс-браузерным, за исключением того, что вы не протестировали должным образом объект XHR браузера. Я также добавлю это к ответу. - person Fabrício Matté; 04.06.2012
comment
Ctrl+F5 ваш firefox и попробуйте мой скрипт. Он должен делать именно то, что вы хотите, и быть кроссбраузерным. Если нет, попробуйте воспроизвести проблему в jsfiddle или еще один живой пейзаж. - person Fabrício Matté; 04.06.2012
comment
Спасибо за Ваш ответ. Это всего лишь пример кода из моих классов, поэтому кроссбраузерная совместимость не так важна. - person jllj; 04.06.2012
comment
Хорошо, я вижу. Тогда откажитесь от части кросс-браузерного кода, мой код выше должен, по крайней мере, бесконечно зацикливаться, как следует из вашего вопроса. Если вам нужен .readyState==3, используйте в ответе только мой первый блок кода. Сообщите мне, если у вас возникнут проблемы с кодом после. знак равно - person Fabrício Matté; 04.06.2012