Intereting Posts
Как получить несколько полей Multi Values PHP: is_file () и file_exists () возвращают разные результаты в одном файле Подавать изображение с помощью скрипта PHP и напрямую загружать изображение Язык скриптов PHP или язык программирования? Массив, возвращающий значение null, многие для многих. Laravel Неустранимая ошибка: вызов неопределенной функции mcrypt_encrypt () Контроллер нагрузки CodeIgniter в контроллере HMVC file_get_contents – не удалось открыть поток: HTTP-запрос не удался! HTTP / 1.1 404 не найден Кнопка удаления, которая удаляет строку базы данных Передача данных массива из PHP в JasperReports (с помощью PHP / JavaBridge) Как реализовать OpenID-аутентификацию на основе Direct Identity с Zend OpenID Генерация отчетов в PHP (требуется формат pdf, xls, doc, csv) Symfony 2 kpn мгновенный генерировать pdf с выходом соответствует зоне безопасности Каков наилучший способ получить последний элемент массива без его удаления? Возможны ли частные константы в PHP?

Получение прогресса XMLHttpRequest с PHP Script

Я использую javascript для запуска XMLHttpRequest для скрипта PHP, который возвращает данные. В основном я хочу, чтобы у пользователя был индикатор прогресса (вместо кругового круга или что-то еще), который показывает ход получения и получения данных. Я знаю, получаю ли я файл, я мог бы просто проверить заголовок длины контента и использовать его, но в случае скрипта вы не знаете, сколько данных он извлекает.

Ответ на это может быть таким же простым, как «это невозможно», потому что сейчас кажется, что это так. Но в заключение: как вы отслеживаете ход работающего скрипта (php) и XMLHttpRequest?

Если вы используете FireFox (и я уверен, что большинство других браузеров, кроме IE), то есть действительно способ сообщить, сколько данных было передано во время XHR-операции. Если рассматриваемая операция отправляет правильный заголовок, довольно просто использовать эту информацию для расчета процента загруженных данных.

Я написал этот код для определения процента данных, переданных в XHR-операции несколько лет назад, поэтому я извиняюсь за то, что он не отражает годы опыта кодирования, который я получил с тех пор. Я почти наверняка не буду писать это так сейчас! Тем не менее, мне удалось вытащить его и надеяться, что он вам подойдет.

В то время, когда это было написано, IE7 была последней версией Explorer, и я помню, что код не работал в этом, поэтому он содержит код, чтобы предотвратить его инициализацию под IE. Я никогда не пробовал этот код в версии 8 или бета версии 9, и он действительно может работать и в этих версиях, но я не могу ручаться за него. Если вы можете заставить его работать в новой версии IE, пожалуйста, дайте мне знать!

Он работает, запуская код в beforeSend (обратный вызов jQuery предоставляет код, который вы хотите запустить до запуска ajax-запроса), чтобы настроить интервал Javascript (в коде, который я поставил 50 миллисекунд, что, вероятно, слишком часто. 200 miliseconds все равно должно быть много, и накладывать меньше нагрузки на систему). Каждый раз, когда срабатывает таймер интервала, он запускает функцию, которая смотрит на атрибут responseText запроса XHR. Атрибут responseText содержит исходный текст данных, полученных до сих пор. Считая, сколько символов находится там с помощью метода length () string, мы можем определить, сколько байтов было собрано до сих пор.

Чтобы определить процент от общего количества отправляемых данных, это потребует, чтобы ваш код на стороне сервера отправил заголовок длины содержимого с точным подсчетом количества байтов, которое он будет отправлять. Это потребует небольшой уловки с вашей стороны, но не должно быть слишком сложно. Если вы отправляете точный заголовок длины контента, то он используется для вычисления процента полученных данных. Если вы не устанавливаете заголовок содержимого, тогда отображается количество данных, полученных до сих пор.

<script type="text/javascript"> $.ajax ({ beforeSend : function (thisXHR) { // IE doesn't support responseText access in interactive mode if (!$.browser.msie) { myTrigger = setInterval (function () { if (thisXHR.readyState > 2) // When there is partial data available use it to determine how much of the document is downloaded { var dlBytes = thisXHR.responseText.length; if (totalBytes == -1) totalBytes = thisXHR.getResponseHeader ('Content-length'); (totalBytes > 0)? $('#progress').html (Math.round ((dlBytes / totalBytes) * 100) + "%"): $('#progress').html (Math.round (dlBytes / 1024) + "K"); } }, 50); // Check the status every 50 miliseconds } }, complete : function () { // Kill the download progress polling timer if (myTrigger) clearInterval (myTrigger); } }); </script> 

В верхней части головы вы можете использовать 2 запроса ajax. Один, чтобы начать и ждать завершения задания, а другой – проверить ход работы. Я уверен, что большинство браузеров могут выполнять как минимум 2 запроса ajax за раз.

Сценарий PHP (Позволяет называть его job.php), который на самом деле выполняет задание, может обновлять переменную сеанса $ _SESSION ['job_progress'] с процентом завершения задания.

У вас есть еще один PHP-скрипт (Давайте назовем его progress.php), который будет эхом, чтобы это значение, т. Е.

 <?php echo $_SESSION['job_progress']; 

На стороне клиента вы сбрасываете свой запрос ajax на job.php. У вас есть еще один запрос ajax для progress.php, который запускается каждые 3 секунды. Вы обновляете свой индикатор выполнения с возвращаемым значением.

Вы также можете сделать это с помощью одного запроса ajax, если запрос job.php будет возвращен до завершения задания. Затем вы можете использовать один запрос ajax для ping скрипта progress.php.

В некоторых браузерах (firefox для одного) onreadystatechange с readyState 3 (т.е. загрузка) вызывается несколько раз, чтобы отслеживать ход загрузки.

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

Тем не менее, Internet Explorer (по крайней мере, для IE7, не уверен в дальнейшем) не поддерживает это, и это ошибка для запроса responseText или responseBody для readyState 3. Я также слышал, что IE только вызывает onreadystatechange один раз с readyState 3, что сделало бы это довольно бесполезно для вашей цели, но я бы предложил проверить его.

Создайте сеанс. (Возможно, у вас уже есть один). Создайте UID для запроса, когда вы попросите его начать обработку.

Храните где-нибудь на сервере (в базе данных, в файле и т. Д.) Прогресс вместе с SID + UID, по мере продвижения запроса.

Используйте второй запрос ajax с таймером для опроса прогресса по SID + UID.

* Вероятно, вы можете получить только UID, но я нашел, что это более управляемо, когда вы также можете контролировать задачи пользователем / сеансом.