Загрузка прогресса в php, ajax или javascript?

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

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

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

После того, как вы нажмете кнопку «Ok», вы можете начать сбор данных на стороне сервера и сохранить процент, загруженный в сеанс.

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

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

Я думаю, что это простое решение, и все должно быть хорошо.

Мне было нужно то же самое – отслеживание загрузки данных 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) { ... } 

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

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

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

Я делаю это, подбирая результаты.

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

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

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

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

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

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