1

I have some problem on FormData of Angular.js

My code is this:

angular
.module("appFoco", [])
.directive('fileModel', ['$parse', function ($parse) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;

            element.bind('change', function(){
                scope.$apply(function(){
                    modelSetter(scope, element[0].files[0]);
                });
            });
        }
    };
}])
.service('fileUpload', ['$http', function ($http) {
    this.uploadFileToUrl = function(file) {
       var fd = new FormData();
       fd.append('file', file);


       $http.post('/send/sendPlanilha', fd, {
          transformRequest: angular.identity,
          headers: {'Content-Type': undefined}
       })
       .success(function() {
       })
       .error(function() {
       });
    }
 }])
.controller("LoginFormPDF",['$scope','fileUpload', function($scope,fileUpload){

    $scope.sendPlanilha = function(){            
        console.log($scope.email, $scope.nome);
        var file = $scope.myFile;
        console.dir(file);

        $scope.usuario = {"usuarioEmail" : $scope.email, "usuarioNome" : $scope.nome}

        fileUpload.uploadFileToUrl(file);
    }

}]);

When I do the $http.post, the fd on fd.append is empty, and I do not know why this is happend. On fd will have a file like arq.xls .

I already saw many kins of tutorials and I did not find a solution. The backend code is in NodeJs, so I need to take a file on fd.append and send to $http.post for a another function on Nodejs, this function is below:

app.post('/send/sendPlanilha', function(req, res, next){}

So, my question is, Why fd on fd.append is empty? And how I can fix this?

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • I think your POST header should be `multipart/form-data` – Aleksey Solovey Apr 27 '19 at 14:46
  • @AlekseySolovey It is important the `Content-Type` be set to `undefined`. Otherwise the [XHR.send](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send) method will generate incorrect form-data boundaries. When `XHR.send` method detects that the object being sent is a [formData object](https://developer.mozilla.org/en-US/docs/Web/API/FormData), it will set the `Content-Type` header appropriately and include the proper boundary. – georgeawg Apr 27 '19 at 17:31

1 Answers1

1

It is more efficient to send the file directly:

app.service('fileUpload', ['$http', function ($http) {
    this.uploadFileToUrl = function(file) {
       ̶v̶a̶r̶ ̶f̶d̶ ̶=̶ ̶n̶e̶w̶ ̶F̶o̶r̶m̶D̶a̶t̶a̶(̶)̶;̶
       ̶f̶d̶.̶a̶p̶p̶e̶n̶d̶(̶'̶f̶i̶l̶e̶'̶,̶ ̶f̶i̶l̶e̶)̶;̶

       ̶$̶h̶t̶t̶p̶.̶p̶o̶s̶t̶(̶'̶/̶s̶e̶n̶d̶/̶s̶e̶n̶d̶P̶l̶a̶n̶i̶l̶h̶a̶'̶,̶ ̶f̶d̶,̶ ̶{̶
       return $http.post('/send/sendPlanilha', file, {
          transformRequest: angular.identity,
          headers: {'Content-Type': undefined}
       })
    }
}])

The base64 encoding of Content-Type: multipart/form-data adds an extra 33% overhead. And the backend then needs to decode the base64 data.

georgeawg
  • 48,608
  • 13
  • 72
  • 95