AngularJS Upload and Post Multiple Files

放肆的年华 提交于 2021-02-18 08:15:18

问题


So ultimately, what I'm doing is trying to upload and post multiple files to a Django backend using AngularJS. I can post a single file, but it seems like when a FileList object is put in the $http.post data field, the backend no longer detects any files in the POST request.

Here's what the html looks like:

<form enctype="multipart/form-data" action="upload" method="POST">
  <div class="form-group">
    <span class="btn btn-info btn-file">
      <i class="glyphicon glyphicon-file"></i> Browse
      <input class="btn btn-lg btn-info" name="uploadedfile" type="file" accept=".eossa" onchange="angular.element(this).scope().filesUploaded(this.files)" multiple><br/>
    </span>
    <button type="button" class="btn btn-success" ng-click="uploadFiles()" ng-class="{'disabled':!model.files.length}">
      <i class="glyphicon glyphicon-download-alt"></i> Submit
    </button>
  </div>
  <pre ng-repeat="file in model.files" ng-show="file.name">{{file.name}}  ({{file.size/1000}} KB)  {{file.lastModifiedDate}} </pre>
</form>

And here's the relevant JavaScript:

$scope.filesUploaded = function(files) {
    if(files.length < 1) return;
    $scope.model.files = files;
    $scope.$apply();
};

$scope.uploadFiles = function(){
  var fd = new FormData();
  fd.append("file", $scope.model.files);
  Services.uploadFiles(fd)}

Here's my uploadFiles service:

uploadFiles: function(form){
    return $http.post("/api/file-upload/", form, {withCredentials: true, headers: {'Content-Type': undefined }, transformRequest: angular.identity})
  },

The backend does not see anything in the request.FILES in this case; however, if instead of appending $scope.model.files, I append $scope.model.file[0], I do see a file in the request on the backend. In which case, the uploadFiles function looks like this:

$scope.uploadFiles = function(){
  var fd = new FormData();
  fd.append("file", $scope.model.files[0]);
  Services.uploadFiles(fd)
}

So why can't one append a FileList to a Form? How can you POST a FileList?

Thanks


回答1:


First create a directive as pointed out here

.directive('filesModel', function () {
    return {
        restrict: 'A',
        controller: function ($parse, $element, $attrs, $scope) {
            var exp = $parse($attrs.filesModel);
            $element.on('change', function () {
                exp.assign($scope, this.files);
                $scope.$apply();
            });
        }
    };
});

And for the transform function, check this out. You can use a factory like:

    .factory('File', function () {
        return {
            // Define a function to transform form data
            transformRequest: function (data, headersGetter) {
                var fd = data ? new FormData() : null;
                if (data) {
                    angular.forEach(data, function (value, key) {
                        // Is it a file?
                        if (value instanceof FileList) {
                            if (value.length == 1) {
                                fd.append(key, value[0]);
                            } else {
                                angular.forEach(value, function (file, index) {
                                    fd.append(key + '_' + index, file);
                                });
                            }
                        }
                        // Is it an object?
                        else if (typeof value === 'object') {
                            fd.append(key, JSON.stringify(value));
                        } else {
                            fd.append(key, value);
                        }
                    });
                }
                return fd;
            }
        };
    })

Then for the service:

uploadFiles: function(form){
    return $http.post("/api/file-upload/", form, {withCredentials: true, headers: {'Content-Type': undefined }, transformRequest: File.transformRequest})
}

Finally the html:

<input type="file" files-model="<model>"/>

Or this for multiple files

<input type="file" files-model="<model>" multiple/>



回答2:


I've never tried the method above and this may be a cop out but I thought I would turn you on to some libraries.

I would checkout these two awesome AngularJS file upload Repos. I personally use this one.

Both support easy setup multiple file upload.

ng-file-upload

Here's another.

angular-file-upload

Why put in hours of work when dozens of folks have contributed and done it for you?



来源:https://stackoverflow.com/questions/32996339/angularjs-upload-and-post-multiple-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!