это не так просто. если вызов ajax запускает обработку, вы можете сделать ответ chunked / multipart (именно так реализовано большинство dhtml-чатов). Google для "COMET".
в основном это работает так:
- клиент: ajax-вызов, запрашивающий начало длительного действия
- сервер: запустить длительное действие,
echo
0%, flush();
(без завершения скрипта)
- клиент: получает ответ с очищенным содержимым (специальный обратный вызов), отображает значение, но соединение остается открытым!
- сервер: после действия x вычислить процент,
echo
и flush();
- клиент: см. # 3
- сервер: если скрипт завершен, прекратить
- client: обычное событие / обратный вызов для конца скрипта. показать 100%, открыть следующую страницу
я однажды (когда асинхронный javascript был еще новым!) Закодировал небольшую демо-версию ... теперь она уже не работает, но асинхронная часть все еще работает Вы можете найти его здесь: http://wehrlos.strain.at/httpreq/client.html
используемый клиентский код javascript
function asSendSyncMulti() {
var httpReq = new XMLHttpRequest();
showMessage( 'Sending Sync Multipart ' + (++this.reqCount) );
// Sync - wait until data arrives
httpReq.multipart = true;
httpReq.open( 'GET', 'server.php?multipart=true&c=' + (this.reqCount), false );
httpReq.onload = showReq;
httpReq.send( null );
}
function showReq( event ) {
if ( event.target.readyState == 4 ) {
showMessage( 'Data arrives: ' + event.target.responseText );
}
else {
alert( 'an error occured: ' + event.target.readyState );
}
}
серверный php-код для составной части:
<?php
$c = $_GET[ 'c' ];
header('Content-type: multipart/x-mixed-replace;boundary="rn9012"');
sleep( 1 );
print "--rn9012\n";
print "Content-type: application/xml\n\n";
print "<?xml version='1.0'?>\n";
print "<content>Multipart: First Part of Request " . $c . "</content>\n";
print "--rn9012\n";
flush();
sleep( 3 );
print "Content-type: application/xml\n\n";
print "<?xml version='1.0'?>\n";
print "<content>Multipart: Second Part of Request " . $c . "</content>\n";
print "--rn9012--\n";
?>
это не более чем толчок в возможном направлении. не совместимый с html или перекрестный просмотр. используйте JSON вместо XML.
на стороне сервера, кэширование вывода (например, для сжатия) должно быть отключено, иначе flush();
ничего не сделает. и --rn9012
должно быть чем-то, что никогда не встречается в ваших выводимых данных (даже если вы просто отображаете прогресс, но все же).