Если вы используете FireFox (и я уверен, что большинство других браузеров, кроме IE), то действительно есть способ сообщить, сколько данных было передано во время операции XHR. Если рассматриваемая операция отправляет правильный заголовок, эту информацию довольно легко использовать для расчета процента загруженных данных.
Я написал этот код для определения процента данных, переданных в операции XHR несколько лет назад, поэтому я прошу прощения за то, что он не отражает многолетний опыт кодирования, который я получил с тех пор. Я почти наверняка не написал бы это так сейчас! Тем не менее, мне удалось выловить это, и надеюсь, что это пригодится вам.
В то время, когда это было написано, IE7 была последней доступной версией Explorer, и я помню, что код не работал в этом, следовательно, он содержит код для предотвращения его инициализации в IE. Я никогда не пробовал этот код под версией 8 или бета версией 9, и он действительно может работать в этих версиях, но я не могу ручаться за это. Если вы можете заставить его работать в новой версии IE, пожалуйста, дайте мне знать!
Он работает, выполняя код в beforeSend (обратный вызов, который jQuery предоставляет для кода, который вы хотите запустить перед запуском ajax-запроса), чтобы установить интервал Javascript (в коде я поместил 50 миллисекунд, что, вероятно, слишком часто 200 миллисекунд все равно должно быть достаточно, и нагрузка на систему будет меньше. Каждый раз, когда срабатывает таймер интервала, он запускает функцию, которая просматривает атрибут responseText запроса XHR. Атрибут responseText содержит необработанный текст полученных данных. Подсчитав, сколько символов находится там с помощью строкового метода length (), мы можем определить, сколько байтов уже собрано.
Для определения процента от общего объема данных, которые необходимо отправить, для этого потребуется, чтобы ваш код на стороне сервера отправлял заголовок длины содержимого с точным подсчетом количества байтов, которые он собирается отправить. Это потребует немного сообразительности с вашей стороны, но не должно оказаться слишком сложным. Если вы отправляете точный заголовок длины содержимого, то он используется для расчета процента данных, полученных на данный момент. Если вы не установили заголовок содержимого, то вместо этого отображается объем полученных данных.
<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>