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

Может ли функция onprogress быть добавлена ​​в jQuery.ajax() с помощью xhrFields?

Как предлагается здесь: https://gist.github.com/HenrikJoreteg/2502497, я пытаюсь добавить функцию onprogress к моей загрузке файла jQuery.ajax(). Загрузка выполняется нормально, а событие onprogress запускается, но не так, как я ожидал - вместо того, чтобы многократно срабатывать через некоторый промежуток времени, он запускается только один раз, когда загрузка завершена. Есть ли способ указать частоту обновления onprogress? Или я пытаюсь сделать что-то, что нельзя сделать? Здесь мой код:

$.ajax(
{
    async: true,
    contentType: file.type,
    data: file,
    dataType: 'xml',
    processData: false,
    success: function(xml)
    {
        // Do stuff with the returned xml
    },
    type: 'post',
    url: '/fileuploader/' + file.name,
    xhrFields:
    {
        onprogress: function(progress)
        {
            var percentage = Math.floor((progress.total / progress.totalSize) * 100);
            console.log('progress', percentage);
            if (percentage === 100)
            {
                console.log('DONE!');
            }
        }
    }
});
4b9b3361

Ответ 1

Короткий ответ:
Нет, вы не можете делать то, что хотите, используя xhrFields.

Длинный ответ:

В объекте XmlHttpRequest есть два события прогресса:

  • Прогресс ответа (XmlHttpRequest.onprogress)
    Это когда браузер загружает данные с сервера.

  • Прогресс запроса (XmlHttpRequest.upload.onprogress)
    Это когда браузер отправляет данные на сервер (включая параметры POST, файлы cookie и файлы).

В вашем коде вы используете событие прогресса ответа, но вам нужно событие прогресса запроса. Вот как вы это делаете:

$.ajax({
    async: true,
    contentType: file.type,
    data: file,
    dataType: 'xml',
    processData: false,
    success: function(xml){
        // Do stuff with the returned xml
    },
    type: 'post',
    url: '/fileuploader/' + file.name,
    xhr: function(){
        // get the native XmlHttpRequest object
        var xhr = $.ajaxSettings.xhr() ;
        // set the onprogress event handler
        xhr.upload.onprogress = function(evt){ console.log('progress', evt.loaded/evt.total*100) } ;
        // set the onload event handler
        xhr.upload.onload = function(){ console.log('DONE!') } ;
        // return the customized object
        return xhr ;
    }
});

Параметр параметра xhr должен быть функцией, которая возвращает собственный объект XmlHttpRequest для использования jQuery.

Ответ 2

Вам нужно добавить обработчик события к самому запросу, прежде чем он будет отправлен. jQuery.ajax позволяет это через свойство beforeSend http://api.jquery.com/jQuery.ajax/

например: http://www.dave-bond.com/blog/2010/01/JQuery-ajax-progress-HMTL5/

* EDIT * Обязательно посмотрите на второй пример кода этого примера. Я считаю, что первый из них устарел с современными версиями jQuery.

$.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;
        //Do something with upload progress
        console.log(percentComplete);
      }
    }, false);
    //Download progress
    xhr.addEventListener("progress", function(evt){
      if (evt.lengthComputable) {
        var percentComplete = evt.loaded / evt.total;
        //Do something with download progress
        console.log(percentComplete);
      }
    }, false);
    return xhr;
  },
  type: 'POST',
  url: "/",
  data: {},
  success: function(data){
    //Do something success-ish
  }
});