Прогресс загрузки в php, ajax или javascript? - PullRequest
2 голосов
/ 16 апреля 2009

Кто-нибудь знает, как я могу отобразить ход загрузки с завершенным% на моей стороне клиента, пока система все еще получает данные на стороне сервера.

Например, когда я нажимаю кнопку «ОК» на стороне клиента, он вызывает серверную часть для сбора данных из базы данных, весь процесс может занять от 2 до 3 минут. Как я могу отобразить ход загрузки на стороне клиента (о том, сколько% было выполнено кодирования)?

Как я могу сделать это в php, ajax или javascript?

Ответы [ 6 ]

3 голосов
/ 05 января 2010

Мне нужно было сделать то же самое - отслеживать ход загрузки данных Ajax - поэтому я опубликую решение, которое я использовал в случае, если кто-то натолкнется на эту тему:

var req = new XMLHttpRequest();

req.addEventListener("progress", onUpdateProgress, false);
req.addEventListener("load", onTransferComplete, false);
req.addEventListener("error", onTransferFailed, false);
req.addEventListener("abort", onTransferAborted, false);

req.open("GET", ..., true);

...

req.send()

function onUpdateProgress(e) {
  if (e.lengthComputable) {
    var percent_complete = e.loaded/e.total;
    document.getElementById("progressMessage").value = Math.round(percentComplete*100) +"% [ " + Math.round(e.loaded / 1000) + " KB ]";
    ...
  } else {
    // Length not known, to avoid division by zero
  }
}

function onTransferComplete(e) { ... }

function onTransferFailed(e)   { ... }

function onTransferAborted(e)  { ... }
2 голосов
/ 16 апреля 2009

это не так просто. если вызов ajax запускает обработку, вы можете сделать ответ chunked / multipart (именно так реализовано большинство dhtml-чатов). Google для "COMET".

в основном это работает так:

  1. клиент: ajax-вызов, запрашивающий начало длительного действия
  2. сервер: запустить длительное действие, echo 0%, flush(); (без завершения скрипта)
  3. клиент: получает ответ с очищенным содержимым (специальный обратный вызов), отображает значение, но соединение остается открытым!
  4. сервер: после действия x вычислить процент, echo и flush();
  5. клиент: см. # 3
  6. сервер: если скрипт завершен, прекратить
  7. 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 должно быть чем-то, что никогда не встречается в ваших выводимых данных (даже если вы просто отображаете прогресс, но все же).

2 голосов
/ 16 апреля 2009

Как только вы нажмете кнопку «ОК», вы можете начать получать данные на стороне сервера и сохранять процент загрузки в сеансе.

Таким образом, на стороне клиента вы можете сделать запрос через AJAX к другому php-скрипту, возвращающему загруженный процент.

В итоге у вас будет 2 серверных сценария (один для извлечения данных, а другой - для процентов) и один клиентский запрос AJAX.

Я думаю, что это простое решение, и оно должно подойти.

0 голосов
/ 22 мая 2009

многокомпонентные / х-смешанных заменить; с промывкой должен работать в среде без нагрузки с балансировкой нагрузки. Подходы, основанные на периодических запросах GET для проверки хода выполнения, не будут успешными в средах, где последующие запросы могут отправляться на другой сервер.

0 голосов
/ 16 апреля 2009

jQuery может отображать заставку (div) во время выполнения запроса ajax. Это можно сделать для каждого запроса с помощью .ajaxStart и .ajaxEnd (или .ajaxStop), или более сложный подход - использовать dojo.io.bind Dojo или следовать шаблону периодического обновления ниже.

Периодическое обновление

0 голосов
/ 16 апреля 2009

Я делаю это, разбивая на страницы результаты.

Первый запрос - получить счет. Затем разбейте запрос на набор групп. Затем начните запрашивать группы по одной за раз.

Например: если нужно вернуть 100 записей, я делю их на группы по 10. Тогда я могу легко отобразить 10% ... 20% ... и т. Д.

Я не знаю, как это сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...