Подтвердить что ты не робот

Прогресс загрузки 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);

Большое спасибо

Бен

4b9b3361

Ответ 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.