Любой знает, как я могу показать ход загрузки с завершенным% на моей стороне клиента, пока система все еще получает данные на стороне сервера.
Например, когда я нажимаю кнопку «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».
в основном это работает так:
echo
0%, flush();
(без завершения скрипта) echo
и flush();
Я один раз (когда асинхронный 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 для проверки прогресса, не будут успешными в средах, где последующие запросы могут перейти к другому концу.