$http上载文件在AngularJS中的进度

$http上载文件在AngularJS中的进度,angularjs,Angularjs,如何从正在上载图像的AngularJS$http POST请求中获取“进度”事件?是否可以在客户端执行此操作,或者是否需要服务器在接收数据时报告进度?我认为$http.post()不能用于此操作 至于客户端,它应该与HTML5浏览器配合使用,但您可能需要创建自己的XMLHttpRequest对象和onprogresslistener。有关想法,请参阅。我认为Angular没有内置的东西来处理上传 我认为你最好的选择是使用类似的东西。解决方案的一个想法是创建一个服务,将{progress:0}作为

如何从正在上载图像的AngularJS$http POST请求中获取“进度”事件?是否可以在客户端执行此操作,或者是否需要服务器在接收数据时报告进度?

我认为$http.post()不能用于此操作


至于客户端,它应该与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有一些扩展:
    XMLHttpRequest
    接受可选参数。上面的代码没有处理这个问题,但是AngularJS无论如何都不使用这些扩展

  • 可能的用途之一(如果您希望显示所有当前请求,并可能实现一些“取消”按钮):

$(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(…)
      on
      onprogress
      显示百分比范围。我确认您仍然需要自己完成。
      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) + '%');
      });