Может ли функция 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!');
}
}
}
});
Ответы
Ответ 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
}
});