Как я могу получить событие "прогресс" из моего запроса на HTTP-запрос AngularJS $http, который загружает изображение? Возможно ли это сделать на стороне клиента или мне нужен сервер, чтобы сообщить о прогрессе, когда он получает данные?
$ http загружает файл прогресса в AngularJS
Ответ 1
Я не думаю, что для этого можно использовать $http.post().
Что касается клиентской стороны, он должен работать с браузером HTML5, но вам, вероятно, придется создать свой собственный объект XMLHttpRequest и onprogress
прослушиватель. См. AngularJS: статус отслеживания каждого загружаемого файла одновременно для идей.
Ответ 2
Вы также можете использовать простую/легкую angular-file-upload директиву, которая позаботится об этом. Он поддерживает drag & падение, прогресс/прерывание файла и загрузку файлов для браузеров, отличных от HTML5, с помощью плагина FileAPI flash
<div ng-controller="MyCtrl">
<input type="file" ng-file-select="onFileSelect($files)" multiple>
</div>
JS:
//inject angular file upload directive.
angular.module('myApp', ['angularFileUpload']);
var MyCtrl = [ '$scope', '$upload', function($scope, $upload) {
$scope.onFileSelect = function($files) {
//$files: an array of files selected, each file has name, size, and type.
for (var i = 0; i < $files.length; i++) {
var $file = $files[i];
$upload.upload({
url: 'my/upload/url',
file: $file,
progress: function(e){}
}).then(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
});
}
}
}];
Ответ 3
Использование чистого angular:
function upload(data) {
var formData = new FormData();
Object.keys(data).forEach(function(key){formData.append(key, data[key]);});
var defer = $q.defer();
$http({
method: 'POST',
data: formData,
url: <url>,
headers: {'Content-Type': undefined},
uploadEventHandlers: { progress: function(e) {
defer.notify(e.loaded * 100 / e.total);
}}
}).then(defer.resolve.bind(defer), defer.reject.bind(defer));
return defer.promise;
}
и где-то еще...
// file is a JS File object
upload({avatar:file}).then(function(responce){
console.log('success :) ', response);
}, function(){
console.log('failed :(');
}, function(progress){
console.log('uploading: ' + Math.floor(progress) + '%');
});
Ответ 4
Я не думаю, что у Angular есть что-то встроенное для обработки загрузок.
Я думаю, что ваш лучший выбор - использовать что-то вроде jQuery File Upload. Идея для решения заключалась бы в создании Сервиса, который возвращает {progress:0}
по умолчанию, а затем внутри себя, реализует обратный вызов обновления процесса загрузки файла jQuery, который затем просто продолжает обновлять прогресс. Благодаря привязке Angular процесс загрузки будет синхронизирован.
angular.module('myApp.services', [])
.factory('Uploader', function() {
var uploaderService = {};
var status = { progress: 0 };
uploaderService.upload = function(inputEl) {
inputEl.fileupload({
/* ... */
progressall: function (e, data) {
status.progress = parseInt(data.loaded / data.total * 100, 10);
}
});
};
return uploaderService;
});
Ответ 5
Вот еще одно решение:
window.XMLHttpRequest = (function (orig) {
if (orig) {
var intercept = [],
result = function () {
var r = new orig();
if (r.upload) {
$(r).on(
'abort error load loadend loadstart progress',
function (e) {
$(document).trigger('upload.XHR', e);
}
);
}
if (intercept.length) {
intercept[0].push({
request:r
});
}
return r;
};
result.grab = function (f) {
intercept.unshift([]);
f();
return intercept.shift();
};
return result;
}
return function () {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {}
throw new Error("This browser does not support XMLHttpRequest.");
};
}(window.XMLHttpRequest));
Примечания:
-
В настоящее время функция AngularJS хранит ссылку на
window.XMLHttpRequest
как частную переменнуюXHR
, а затем использует ее следующим образом:new XHR()
. Я сомневаюсь, что это когда-нибудь изменится, поэтому вышеприведенный выше код должен работать нормально. -
Mozilla имеет несколько расширений:
XMLHttpRequest
принимает необязательные аргументы. Код выше не справляется с этим, но AngularJS не использует эти расширения в любом случае. -
Одно из возможных применений (если вы хотите показать все текущие запросы и, возможно, реализовать некоторую кнопку "Отмена" ):
$(document).on('upload.XHR', function (_e, e) {
switch (e.type) {
// do your thing here
}
});
- Еще одно возможное использование:
var list = window.XMLHttpRequest.grab(function () {
// start one or more $http requests here, or put some code
// here that indirectly (but synchronously) starts requests
$http.get(...);
couchDoc.save();
couchDoc.attach(blob, 'filename.ext');
// etc
});
list[0].request.upload.addEventListener(...);
- Или вы можете комбинировать оба подхода с некоторыми изменениями в коде выше.
Ответ 6
вы можете использовать это, когда Im использует простую функцию angular для загрузки файла и переменной $scope.progressBar, чтобы проверить ход загрузки...
$scope.functionName = function(files) {
var file = files[0];
$scope.upload = $upload.upload({
url: 'url',
method: 'POST',
withCredentials: true,
data: {type:'uploadzip'},
file: file, // or list of files ($files) for html5 only
}).progress(function(evt) {
console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
$scope.progressBar = parseInt(100.0 * evt.loaded / evt.total);
}).success(function(data, status, headers, config) {
console.log('upload succesfully...')
}).error(function(err) {
console.log(err.stack);
})
}