Вот моя функция AJAX:
/**
* Send an AJAX request
*
* @param url The URL to call (located in the /ajax/ directory)
* @param data The data to send (will be serialised with JSON)
* @param callback The function to call with the response text
* @param silent If true, doesn't show errors to the user
* @param loader The element containing "Loading... Please wait"
*/
AJAX = function(url,data,callback,silent,loader) {
var a,
attempt = 0,
rsc = function() {
if( a.readyState == 4) {
if( a.status != 200) {
if( a.status > 999) { // IE sometimes throws 12152
attempt++;
if( attempt < 5)
send();
else if( !silent) {
alert("HTTP Error "+a.status+" "+a.statusText+"<br />Failed to access "+url);
}
}
else if(!silent) {
alert("HTTP Error "+a.status+" "+a.statusText+"\nFailed to access "+url);
}
}
else {
callback(JSON.parse(a.responseText));
}
}
},
to = function() {
a.abort();
attempt++;
if( attempt < 5)
send();
else if( !silent) {
alert("Request Timeout\nFailed to access "+url);
}
};
data = JSON.stringify(data);
var send = function() {
if( loader && attempt != 0) {
loader.children[0].firstChild.nodeValue = "Error... retrying...";
loader.children[1].firstChild.nodeValue = "Attempt "+(attempt+1)+" of 5";
}
a = new XMLHttpRequest();
a.open("POST","/ajax/"+url,true);
a.onreadystatechange = rsc;
a.timeout = 5000;
a.ontimeout = to;
a.setRequestHeader("Content-Type","application/json");
a.send(data);
};
send();
};
Общая идея - попытаться выполнить запрос до пяти раз.Иногда происходит сбой IE с необычной ошибкой HTTP (12xxx), а иногда сервер может не отвечать.
Проблема, с которой я столкнулся, заключается в том, что вызов abort()
не прерывает соединение.Чтобы проверить, я сделал простой PHP-скрипт:
<?php
sleep(60);
touch("test/".uniqid());
die("Request completed.");
?>
Вызов touch()
создает файл с текущим uniqid()
- просмотрев время модификации, я вижу время окончания sleep(60)
.
Ожидаемое поведение:
Запрос отправлен
Через пять секунд текст изменится на «Ошибка ... Повторная попытка ... Попытка 2/5»
Повторите вышеупомянутое до Попытки 5/5, затем потерпите неудачу.
Пять вызовов к файлу PHP прерваны, или либо будет пять файлов в папке «test», с интервалом в 5 секунд, либо будетнет, потому что ignore_user_abort выключен.
Наблюдаемое поведение (в IE9):
Запрос отправлен
Текст попытки появляется и изменяется, как и должен
После пяти попыток отображается сообщение об ошибке
Я не могу загрузить ни одной страницы в течение пяти полных минут.
На сервере пять файлов с интервалом в одну минуту
Донне знаю, что с этим делать, потому что на стороне сервера запросов 3,4 и 5 отправляются через несколько минут после появления в браузере сообщения об ошибке «Тайм-аут».
Если это имеет какое-либо значение, страница, выполняющая вызовы AJAX, находится в iframe.Перезагрузка iframe (использование iframe.contentWindow.location.reload()
НЕ устраняет проблему, она все еще ожидает выполнения этих пяти запросов.
Почему это происходит? Как я могу это исправить?
РЕДАКТИРОВАТЬ: Я снова запустил тест, используя Инструменты разработчика для мониторинга сетевой активности. Результат:
URL Method Result Type Received Taken Initiator
/ajax/testto (Aborted) 0 B < 1 ms (Pending...)
/ajax/testto (Aborted) 0 B 125 ms (Pending...)
/ajax/testto (Aborted) 0 B 125 ms (Pending...)
/ajax/testto (Aborted) 0 B 125 ms (Pending...)
/ajax/testto (Aborted) 0 B 124 ms (Pending...)