Прогресс загрузки XHR составляет 100% с самого начала
Я пытаюсь добавить новую функцию XMLHTTPRequestUpload для загрузки некоторых файлов на php script, в основном это работает нормально, загрузка начинается, я получаю ответ завершения и т.д., но прогресс, похоже, не работает.
Глядя на то, что значение event.loaded - В firefox мне кажется, что получается случайное значение между 0 и размером файла; в Chrome (где я больше всего работаю), я получаю общий размер файла, хотя readistate не достиг "4", а в окне инструментов разработчика все еще отображается файл для загрузки?
Любые идеи?
Вот мой код:
var xhr = new XMLHttpRequest()
xhr.upload.addEventListener('progress', function(event) {
if (event.lengthComputable) {
$('ajaxFeedbackDiv').innerHTML = event.loaded + ' / ' + event.total;
}
}, false);
xhr.onreadystatechange = function(event) {
if (event.target.readyState == 4) {
updateFileList();
}
};
xhr.open("POST", "_code/upload.php");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("X-File-Type", file.type);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr(file);
Большое спасибо
Бен
Ответы
Ответ 1
Недавно мне также было трудно установить прослушиватель событий для событий XHR onprogress. Я закончил его реализацию анонимной функцией, которая прекрасно работает:
xhr.upload.onprogress = function(evt)
{
if (evt.lengthComputable)
{
var percentComplete = parseInt((evt.loaded / evt.total) * 100);
console.log("Upload: " + percentComplete + "% complete")
}
};
Я наткнулся на множество других ошибок на этом пути, поэтому, скорее всего, один из них отключил прослушиватель событий. Единственная разница между тем, что у вас есть, и моей настройкой - это использование xhr.sendAsBinary().
Ответ 2
Я столкнулся с аналогичной проблемой сам, где моя функция обработчика событий для событий progress
на XMLHttpRequest
выполнялась только один раз - когда загрузка была завершена.
Причина проблемы оказалась простой - в Google Chrome (возможно, в других браузерах тоже я не тестировал) событие progress
будет запускаться только последовательно, если загрузка была запущена на второй или второй, Другими словами, если ваша загрузка заканчивается быстро, тогда вы, скорее всего, получите только 100% progress
событие.
Здесь пример кода, событие progress
только один раз завершается на 100% (https://jsfiddle.net/qahs40r6/):
$.ajax({
xhr: function()
{
var xhr = new window.XMLHttpRequest();
//Upload progress
xhr.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log("Upload ", Math.round(percentComplete*100) + "% complete.");
}
}, false);
return xhr;
},
type: 'POST',
url: "/echo/json/",
data: {json: JSON.stringify(new Array(20000))}
});
Выход консоли:
Upload 100% complete.
Но если вы добавите дополнительный ноль к размеру массива (увеличение размера полезной нагрузки в 10 раз - https://jsfiddle.net/qahs40r6/1/):
$.ajax({
xhr: function()
{
var xhr = new window.XMLHttpRequest();
//Upload progress
xhr.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log("Upload ", Math.round(percentComplete*100) + "% complete.");
}
}, false);
return xhr;
},
type: 'POST',
url: "/echo/json/",
data: {json: JSON.stringify(new Array(200000))}
});
Затем вы получаете нормальную прогрессию событий progress
:
Upload 8% complete.
Upload 9% complete.
Upload 19% complete.
Upload 39% complete.
Upload 50% complete.
Upload 81% complete.
Upload 85% complete.
Upload 89% complete.
Upload 100% complete.
Это зависит от скорости вашего интернет-соединения, поэтому ваш пробег будет отличаться. Например, если вы возьмете первый пример и используете инструменты разработчика Chrome, чтобы замедлить соединение с имитируемым "медленным 3G", вы увидите серию событий progress
.
Аналогичным образом, если вы разрабатываете локально и загружаете данные на локальный веб-сервер, вы, вероятно, никогда не увидите события progress
, потому что загрузка завершится мгновенно. Вероятно, это то, что @brettjonesdev видел в локальном хосте и удаленном развертывании prod.