25

画像をアップロードしているAngularJS$http POSTリクエストから「progress」イベントを取得するにはどうすればよいですか?これをクライアント側で行うことは可能ですか、それともサーバーがデータを受信するときに進行状況を報告する必要がありますか?

4

6 に答える 6

21

純粋な角度の使用:

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) + '%');
});
于 2017-01-30T06:26:20.890 に答える
17

これらを処理するsimple/lightweightangular -file-uploadディレクティブを使用することもできます。FileAPIフラッシュシムを使用したHTML5以外のブラウザのドラッグアンドドロップ、ファイルの進行状況/中止、およびファイルのアップロードをサポートします

<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);
      }); 
    }
  }
}];
于 2013-11-14T18:08:02.783 に答える
15

$ http.post()をこれに使用できるとは思いません。

クライアント側に関しては、HTML5ブラウザーで動作するはずですが、おそらく独自のXMLHttpRequestオブジェクトとonprogressリスナーを作成する必要があります。アイデアについては、AngularJS:同時にアップロードされている各ファイルのステータスの追跡を参照してください。

于 2013-01-12T03:48:41.307 に答える
3

Angularにはアップロードを処理するための何かが組み込まれているとは思いません。

あなたの最善の策は、jQueryFileUploadのようなものを使用することだと思います。ソリューションのアイデアは、{progress:0}デフォルトとして返され、それ自体の内部にサービスを作成し、jQuery File Uploadの進行状況更新コールバックを実装します。これにより、進行状況が更新され続けます。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;
});
于 2013-01-12T14:09:18.910 に答える
2

別の解決策は次のとおりです。

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はこれらの拡張機能を使用しません。

  • 考えられる使用法の1つ(現在のすべてのリクエストを表示し、[キャンセル]ボタンを実装する場合):

$(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(...);
  • または、上記のコードにいくつかの変更を加えて、両方のアプローチを組み合わせることができます。
于 2013-03-23T19:42:56.830 に答える
0

これを使用して、単純な角度関数を使用してファイルをアップロードし、$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);
 }) 
}
于 2016-04-04T10:50:21.507 に答える