$http上载文件在AngularJS中的进度
如何从正在上载图像的AngularJS$http POST请求中获取“进度”事件?是否可以在客户端执行此操作,或者是否需要服务器在接收数据时报告进度?我认为$http.post()不能用于此操作$http上载文件在AngularJS中的进度,angularjs,Angularjs,如何从正在上载图像的AngularJS$http POST请求中获取“进度”事件?是否可以在客户端执行此操作,或者是否需要服务器在接收数据时报告进度?我认为$http.post()不能用于此操作 至于客户端,它应该与HTML5浏览器配合使用,但您可能需要创建自己的XMLHttpRequest对象和onprogresslistener。有关想法,请参阅。我认为Angular没有内置的东西来处理上传 我认为你最好的选择是使用类似的东西。解决方案的一个想法是创建一个服务,将{progress:0}作为
至于客户端,它应该与HTML5浏览器配合使用,但您可能需要创建自己的XMLHttpRequest对象和
onprogress
listener。有关想法,请参阅。我认为Angular没有内置的东西来处理上传
我认为你最好的选择是使用类似的东西。解决方案的一个想法是创建一个服务,将{progress:0}
作为默认值返回,然后在其内部实现jQuery File Upload的progress update回调,该回调随后只会继续更新进度。由于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;
});
下面是另一个解决方案:
window.XMLHttpRequest=(函数(orig){
如果(原){
var intercept=[],
结果=函数(){
var r=新的源代码();
if(r.upload){
$(r)(
'中止错误加载加载结束加载开始进度',
职能(e){
$(document.trigger('upload.XHR',e);
}
);
}
if(截距长度){
拦截[0]。推送({
请求:r
});
}
返回r;
};
result.grab=函数(f){
截取。取消移位([]);
f();
返回intercept.shift();
};
返回结果;
}
返回函数(){
尝试{returnnewActiveXObject(“Msxml2.XMLHTTP.6.0”);}catch(e1){}
请尝试{返回新的ActiveXObject(“Msxml2.XMLHTTP.3.0”);}catch(e2){}
尝试{returnnewActiveXObject(“Msxml2.XMLHTTP”);}catch(e3){}
抛出新错误(“此浏览器不支持XMLHttpRequest。”);
};
}(window.XMLHttpRequest));
注:
- AngularJS当前将对
的引用存储为私有window.XMLHttpRequest
变量,然后像这样使用它:XHR
。我怀疑这种情况是否会改变,所以上面类似垫片的代码应该可以正常工作new XHR()
- Mozilla有一些扩展:
接受可选参数。上面的代码没有处理这个问题,但是AngularJS无论如何都不使用这些扩展XMLHttpRequest
- 可能的用途之一(如果您希望显示所有当前请求,并可能实现一些“取消”按钮):
$(document).on('upload.XHR',函数(\u e,e){
开关(e型){
//在这里做你的事
}
});
- 另一种可能的用途:
var list=window.XMLHttpRequest.grab(函数(){
//在此处启动一个或多个$http请求,或放置一些代码
//在这里,它间接(但同步)启动请求
$http.get(…);
couchDoc.save();
attach(blob,'filename.ext');
//等
});
列表[0].request.upload.addEventListener(…);
- 或者,您可以将这两种方法结合起来,并对上面的代码进行一些修改
- 您还可以使用简单/轻量级指令来处理这些内容。
它支持使用FileAPI flash shim的非HTML5浏览器的拖放、文件进程/中止和文件上载
<div ng-controller="MyCtrl">
<input type="file" ng-file-select="onFileSelect($files)" multiple>
</div>
JS:
//插入角度文件上载指令。
angularFileUpload模块('myApp',['angularFileUpload']);
var MyCtrl=['$scope','$upload',函数($scope,$upload){
$scope.onFileSelect=函数($files){
//$files:选定文件的数组,每个文件都有名称、大小和类型。
对于(变量i=0;i<$files.length;i++){
var$file=$files[i];
$upload.upload({
url:'my/upload/url',
文件:$file,
进展:职能(e){}
}).then(函数(数据、状态、标题、配置){
//文件已成功上载
控制台日志(数据);
});
}
}
}];
您可以使用此选项,其中Im使用简单的角度函数上载文件,使用$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);
})
}
使用纯角度:
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;
}
你需要像“完成10%”,然后是“完成25%”之类的精确信息吗?或者仅仅需要某种动画图形来表示工作正在进行吗?不需要。在.net的试用解决方案中。我只得到100%的每一个文件。没有进展(11%,25%)@danial您在.net中有进展的例子吗。我必须更改服务器端的spmething吗?Progress callbacl only report 100%查看wiki页面并将您的问题发布到github问题上。您可能需要更改某些服务器设置和代理以启用进度报告。在其他项目(也包括.NET)中,使用了我的同事,文件进度正常。或者可能是我的上载速度太快,无法实际查看progress@Vlado,我使用了
范围。$apply(…)
ononprogress
显示百分比范围。我确认您仍然需要自己完成。
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) + '%');
});