|
|
|
| Здравствуйте,
скажите пожалуйста существует ли способ практически безотказной обработки функцией полученных назад от php данных?
возникает такая ситуация, что XMLHttpRequest запустил php файл и он отработал, данные из ajax внеслись в БД, но обратные данные print(); не всегда получают статус 200 и пользователь не видит вывода на экране...
function processReqChange(httpRequest)
{
document.getElementById('loader').innerHTML = '<img src="images/hl.gif" alt="" />';
if (httpRequest.readyState == 4)
{
clearTimeout(reqTimeout);
if (httpRequest.status == 200)
{
document.getElementById('loader').innerHTML = '';
if(curpost == 0)
{
if (httpRequest.responseText)
document.getElementById('comm_' + curid).innerHTML = httpRequest.responseText;
else
document.getElementById('comm_' + curid).innerHTML = oldtext;
oldid = 0;
oldtext = '';
}
if(curpost == 2)
document.getElementById(curid).innerHTML = document.getElementById(curid).innerHTML + httpRequest.responseText;
}
else
{
document.getElementById('loader').innerHTML = '';
alert(" ERROR ");
}
}
}
|
тобишь я получаю alert с ошибкой.
так оотсылается XMLHttpRequest
httpRequest.onreadystatechange = function() { processReqChange(httpRequest); };//processReqChange;
httpRequest.open("POST", url, true);
httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded;");
httpRequest.setRequestHeader("Content-length", poststr.length);
httpRequest.setRequestHeader("Connection", "close");
httpRequest.send(poststr);
reqTimeout = setTimeout("httpRequest.abort();", 4000);
|
| |
|
|
|
|
|
|
|
для: moonfox
(21.02.2011 в 12:35)
| | Почему данные не всегда получают статус 200 и пользователь не видит вывода на экране?
readyState чему в этом случае равно? | |
|
|
|
|
|
|
|
для: moonfox
(21.02.2011 в 12:35)
| | Попробуйте перевести на русский язык слово onreadystatechange
Функция, кою Вы на это событие "повесили" - она будет "запускаться" в момент всякого изменения свойства readyState, а возможных значений этого свойства - всего ПЯТЬ: 0, 1, 2, 3, 4.
Свойство status - оно иное, чем readyState, возможные значения у него иные, и количество этих значений много больше, а именно СОРОК: 100-101, 200-206, 300-305, 307, 400-417, 500-505.
Ваша функция, включившись последний (четвёртый) раз - когда readyState переходит из состояния 3 в состояние 4, работает всего одно мгновение (доли секунды). Вам почему-то хочется, чтобы именно в эту долю секунды уже произошло изменение другого свойства - свойства status - со значения 100 в значение 200.
А оно НЕ ВСЕГДА так бывает.
Переход с 100 на 200 иногда бывает на мгновение позже.
Но функция у Вас уже отработала - вот Вы и получаете alert с ошибкой через 4 секунды, за которые Вы вполне могли бы ещё пару тысяч раз проверить значение свойства status. Но Вы этого не делаете.
Вы тупо ждёте четыре секунды и потом "кричите" - "Внимание, Ошибка!"
А ошибки - нет, есть глупость.
Каким-то идиотом придуманная и по сей день другими идиотами БЕЗДУМНО в свои скрипты вставляемая. Видимо, этот идиот всегда сначала пукал, а потом чихал. И ему подумалось, что именно так и у всех других людей :-)
-----
Правильная (рабочая) логика скрипта д. б. такой:
1. Создаём объект httpRequest
2. На событие onreadystatechange этого объекта навешиваем функцию Function_number_ONE (), которая проверяет значение свойства readyState. Если оно меньше, чем 4, то просто делается выход из этой функции (return). Функция Function_number_ONE () ещё раз САМА (безо всякого таймера) включится, когда произойдёт очередное изменение свойства readyState.
3. А вот если значение readyState равно 4 (ответ пришёл), то функция Function_number_ONE () должна вызвать другую функцию - Function_number_TWO (), которая будет проверять значение свойства status на равенство значению 200. И не тупо - один раз через четыре секунды, а много-много раз через десяток миллисекунд, если значение равно пока что 100 (что означает "продолжение процесса") или НИ ОДНОГО РАЗА, если значение больше, чем 200 - это означает, что уже НИКОГДА не будет 200. Вот только здесь нужен таймер. И не со значением 4000 по времени, а, например, со значением 10 (или даже 5), но с каким-то счётчиком количества обращений - 100 раз (или 1000, в зависимости от Вашего желания). И с обязательным прекращением процесса тайминга, если status > 200 - это реальная ошибка, responseText у Вас по-любому будет пустой в этом случае.
-----
Разумеется, всё могло бы быть реализовано много проще, если бы браузер поддерживал событие onstatuschange, но поддержки такого события НЕТ. | |
|
|
|
|
|
|
|
для: Абырвалг
(22.02.2011 в 09:44)
| | спасибо за разъяснение,
наверно проблема заключается в том, что многие не читают теорию, а учатся на готовых примерах, реально не понимая "эталонны" ли они....
насколько я вас понял, должно выйти примерно так ?
httpRequest.onreadystatechange = function() { check4(httpRequest) };//processReqChange;processReqChange(httpRequest);
httpRequest.open("POST", url, true);
httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded;");
httpRequest.setRequestHeader("Content-length", poststr.length);
httpRequest.setRequestHeader("Connection", "close");
httpRequest.send(poststr);
//reqTimeout = setTimeout("httpRequest.abort();", 4000);
document.getElementById('loader').innerHTML = '<img src="images/hl.gif" alt="" />';
function check4(httpRequest)
{
if (httpRequest.readyState != 4)
return;
else processReqChange(httpRequest);
}
var c = 0;
function processReqChange(httpRequest)
{
reqTimeout = setInterval(function() { processReqChange(httpRequest) }, 5);
if(c == 100)
{
clearInterval(reqTimeout);
alert(" error ");
}
if (httpRequest.status == 200)
{
clearInterval(reqTimeout);
document.getElementById('loader').innerHTML = '';
if(curpost == 0)
{
if (httpRequest.responseText)
document.getElementById('comm_' + curid).innerHTML = httpRequest.responseText;
else
document.getElementById('comm_' + curid).innerHTML = oldtext;
oldid = 0;
oldtext = '';
}
if(curpost == 2)
document.getElementById(curid).innerHTML = document.getElementById(curid).innerHTML + httpRequest.responseText; }
if (httpRequest.status > 200)
{
clearInterval(reqTimeout);
document.getElementById('loader').innerHTML = '';
alert(" error ");
}
c ++;
}
|
| |
|
|
|
|
|
|
|
для: moonfox
(22.02.2011 в 18:52)
| |
var CNTR = 0, TMR; //глобальные переменные, как и httpRequest
httpRequest.onreadystatechange = check4;
...[нужные Вам параметры]...
function check4 () {if (httpRequest.readyState != 4) return; processReqChange ()}
function processReqChange ()
{
if (CNTR == 200) {clearTimeout (TMR); alert ('error100'); return} //проверяете status максимум 200 раз
if (httpRequest.status < 200) {++CNTR; TMR = setTimeout ("processReqChange ()", 5)}
else if (httpRequest.status > 200) {clearTimeout (TMR); alert ('error200+'); return}
else {clearTimeout (TMR); и делаете то, что Вам надо при нормальном ответе}
}
|
| |
|
|
|
|
|
|
|
для: Абырвалг
(22.02.2011 в 20:08)
| | спасибо, а скажите пожалуйста в моем последнем примере, что именно радикально не целесообразно? | |
|
|
|
|