как получить прогресс от xmlhttprequest

<p>можно ли получить ход выполнения запроса xmlhttprequest (загружено байт, загружено байт)?</p><p>это было бы полезно, чтобы показать индикатор выполнения, когда пользователь загружает большой файл. стандартный api, кажется, не поддерживает его, но, возможно, есть какое-то нестандартное расширение в любом из браузеров? в конце концов, это довольно очевидная возможность, поскольку клиент знает, сколько байт было загружено/загружено.</p><p>примечание: мне известна альтернатива "опросить сервер на предмет прогресса" (это то, чем я сейчас занимаюсь). основная проблема с этим (кроме сложного кода на стороне сервера) заключается в том, что, как правило, при загрузке большого файла подключение пользователя полностью скрывается, поскольку большинство провайдеров предлагают плохой восходящий поток. поэтому делать дополнительные запросы не так быстро, как я надеялся. я надеялся, что найдется способ (возможно, нестандартный) получить эту информацию, которую браузер всегда имеет.</p>

<p>для загруженных байтов это довольно просто. просто следите за событием <code>xhr.upload.onprogress</code>. браузер знает размер файлов, которые он должен загрузить, и размер загруженных данных, поэтому он может предоставить информацию о ходе выполнения.</p><p>для загруженных байтов (при получении информации с помощью <code>xhr.responsetext</code>) это немного сложнее, потому что браузер не знает, сколько байтов будет отправлено в запросе сервера. единственное, что браузер знает в этом случае, это размер байтов, которые он получает.</p><p>для этого есть решение: достаточно установить заголовок <code>content-length</code> в скрипте сервера, чтобы получить общий размер байтов, которые браузер собирается получить.</p><p>для получения дополнительной информации посетите <a href="https://developer.mozilla.org/en/using\_xmlhttprequest">https://developer.mozilla.org/en/using\_xmlhttprequest</a> .</p><p>пример: мой серверный скрипт читает файл zip (это занимает 5 секунд):</p><pre><code>$filesize=filesize('test.zip'); header("content-length: " . $filesize); // set header length // if the headers is not set then the evt.loaded will be 0 readfile('test.zip'); exit 0; </code></pre><p>теперь я могу следить за процессом загрузки серверного скрипта, потому что я знаю его общую длину:</p><pre><code>function updateprogress(evt) { if (evt.lengthcomputable) { // evt.loaded the bytes the browser received // evt.total the total bytes set by the header // jquery ui progress bar to show the progress on screen var percentcomplete = (evt.loaded / evt.total) * 100; $('#progressbar').progressbar( "option", "value", percentcomplete ); } } function sendreq(evt) { var req = new xmlhttprequest(); $('#progressbar').progressbar(); req.onprogress = updateprogress; req.open('get', 'test.php', true); req.onreadystatechange = function (aevt) { if (req.readystate == 4) { //run any callback here } }; req.send(); } </code></pre>

<p>здесь хорошо обсуждается индикатор прогресса для шаблона ajax:</p><p> <a href="http://ajaxpatterns.org/progress\_indicator">http://ajaxpatterns.org/progress\_indicator</a> </p><p>один из наиболее многообещающих подходов, по-видимому, заключается в открытии второго канала связи с сервером, чтобы узнать, какая часть передачи была завершена.</p>

<p>firefox поддерживает <a href="https://developer.mozilla.org/en/using\_xmlhttprequest#monitoring\_progress">события прогресса загрузки xhr</a> .</p>

<p> <a href="https://developer.mozilla.org/en/using\_xmlhttprequest#in\_firefox\_3.5\_and\_later">firefox 3.5 будет поддерживать событие прогресса загрузки</a> </p>

<p>по всей загруженной информации, кажется, нет способа справиться с этим, но есть нечто похожее на то, что вы хотите загрузить. как только readystate равен 3, вы можете периодически запрашивать responsetext, чтобы получить весь загруженный контент, вплоть до string (это не работает в ie), до тех пор, пока все это не станет доступным, и в этот момент он перейдет к readystate 4. всего байт, загруженные в любой момент времени, будут равны общему количеству байтов в строке, хранящейся в responsetext.</p><p>для подхода "все или ничего" к вопросу о загрузке, так как вам нужно передать строку для загрузки (и можно определить общее количество байтов этого), общее количество байтов, отправленных для readystate 0 и 1, будет равно 0, а общее количество для readystate 2 будет общим количеством байтов в строке, которую вы передали. общее количество байтов, отправленных и полученных в readystate 3 и 4, будет суммой байтов в исходной строке плюс общее количество байтов в responsetext.</p>

<p>если у вас есть доступ к вашей установке apache и вы доверяете стороннему коду, вы можете использовать <a href="http://drogomir.com/blog/2008/6/18/upload-progress-bar-with-mod\_passenger-and-apache">модуль выполнения загрузки apache</a> (если вы используете apache; есть также <a href="http://wiki.codemongers.com/nginxhttpuploadprogressmodule">модуль выполнения загрузки nginx</a> ).</p><p>в противном случае вам придется написать сценарий, который вы можете использовать вне диапазона для запроса статуса файла (например, проверка размера файла в файле tmp).</p><p>в firefox 3 есть работа, которая, я полагаю, добавит поддержку прогресса загрузки в браузер, но она не будет распространяться на все браузеры и будет широко распространена некоторое время (больше жаль).</p>