How do I upload a multipart form in AngularJS?

♀尐吖头ヾ 提交于 2019-12-22 09:57:40

问题


Form view:

        <form enctype="multipart/form-data" ng-submit="upload(file)">

            <input type="file" ng-model="modal.file" accept="image/gif" app-filereader /><br />

            <br>

            <textarea name="description" placeholder="Description" ng-model="description" id="" cols="30" rows="10"></textarea>

            <br>

            <input type="hidden" name="user" ng-model="user" value="{{ user }}" />

            <br>

            <input type="submit" value="Submit" class="network-sensitive button button-block button" />

        </form>

Directive:

.directive('appFilereader', function(
$q
){
    var slice = Array.prototype.slice;

return {
    restrict: 'A'
    , require: '?ngModel'
    , link: function(scope, element, attrs, ngModel){
        if(!ngModel) return;

        ngModel.$render = function(){}

        element.bind('change', function(e){
            var element = e.target;

            $q.all(slice.call(element.files, 0).map(readFile))
            .then(function(values){
                if(element.multiple) ngModel.$setViewValue(values);
                else ngModel.$setViewValue(values.length ? values[0] : null);
            });

            function readFile(file) {
                var deferred = $q.defer();

                var reader = new FileReader()
                reader.onload = function(e){
                    deferred.resolve(e.target.result);
                }
                reader.onerror = function(e) {
                    deferred.reject(e);
                }
                reader.readAsDataURL(file);

                return deferred.promise;
            }

        });

    }

};

});

Upload function in my services:

upload: function(file) {
  var token = $window.sessionStorage.token;

  var url = 'http://url.co/api/posts/creates';

  var $cache = $cacheFactory.get('$http');

  var deffered = $q.defer();

  var data = $cache.get(url);

  if(!data) {
      $http({
        url: url, 
        method: "POST",
        params: { access_token: token },
        data: file,
        headers: {'Content-Type': undefined },
        transformRequest: angular.identity
      }).then(function(res) {
      deffered.resolve(res);
    });
  } else {
    deffered.resolve(data);
  }

  return deffered.promise;
  }

I've not included the controller code as it's just relaying the form data from the modal to the service and that part's working.

The problem I'm having is that the file is being submitted as encoded data (my knowledge is a bit shaky about binary data and blobs etc). And my API (written in Symfony2) is expecting a normal file submission as opposed to the data string.

So how would I convert that binary blob into an image file I can then submit? Or am I missing something?


回答1:


use this module https://github.com/danialfarid/angular-file-upload is very simple to use.

ex:

    var $file;//single file 
    $scope.sendFiles= function(){
     $upload.upload({
                        url: yourUrl,
                        method: "POST",
                        data: { data: $scope.yourOtherObject },
                        file: $file
                    }).success(function (data, status, headers, config) {
                        // file is uploaded successfully
                        console.log(data);
                        console.log("File upload SUCCESS");
                    }).error(function (data, status) {
                       console.log("File upload FAILED");
                    });
    } 

    $scope.onFileSelect = function ($files) {
                for (var i = 0; i < $files.length; i++) {
                    $file = $files[i];//set a single file
                }
           };

HTML CODE

<input type="file" name="myfile" ng-file-select="onFileSelect($files)" />
<button ng-click='sendFiles()'>Send file</button>



回答2:


The problem is the $http service, by default use content-type as application/json and in your case it must be application/x-www-form-urlencoded To solve this you can use the following directive: https://github.com/nervgh/angular-file-upload/wiki/Module-API, it also has support for send data along with the files.

Another aproach is to use the formData object along with XmlHttpRequest in your directive, like this:

                var data = new FormData();
                var xhr = new XMLHttpRequest();
                data.append('file', files[i], files[i].name);
                xhr.open('POST', scope.mseUploadFile);
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        var result = xhr.responseText;

                        if (scope.callback) {
                            scope.$apply(function () {
                                scope.callback({ $data: result });
                            });
                        }

                    }
                    else if (xhr.readyState == 4 && xhr.status == 400) {
                        scope.$apply(function () {
                            if (scope.onError) {
                                scope.onError({ $error: xhr.responseText });
                            }
                            handleError(xhr.responseText);
                        });

                    }
                };
                xhr.send(data);


来源:https://stackoverflow.com/questions/26162132/how-do-i-upload-a-multipart-form-in-angularjs

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