Прогресс загрузки XHR - 100% от начала - PullRequest
21 голосов
/ 28 июля 2010

Я пробую новую функцию XMLHTTPRequestUpload для загрузки некоторых файлов в сценарий php, она в основном работает нормально, загрузка начинается, я получаю готовый ответ и т. Д., Но прогресс, похоже, не работает.

Смотря что значение event.loaded - в Firefox я, кажется, получаю случайное значение между 0 и размером файла; в Chrome (где я в основном работаю) я получаю общий размер файла, даже если состояние чтения не достигло «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);

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

Ben

Ответы [ 2 ]

19 голосов
/ 30 марта 2011

У меня также недавно были некоторые трудности с настройкой прослушивателя событий для событий 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 ().

4 голосов
/ 10 ноября 2017

Я сам столкнулся с подобной проблемой, когда моя функция обработчика событий для 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 Developer Tools для замедления вашего соединения с имитированным «Медленным 3G», то вы увидите серию событий progress.

Аналогичным образом, если вы разрабатываете локально и загружаете данные на локальный веб-сервер, вы, скорее всего, никогда не увидите события progress, потому что загрузка завершится мгновенно. Вероятно, это то, что @brettjonesdev видел в локальном хосте против удаленного развертывания prod.

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