mkhbragg
mkhbragg

Reputation: 131

Set Content-Type header to multipart?

Angular suggests setting 'Content-Type' header to undefined (https://docs.angularjs.org/api/ng/service/$http) so that the browser can pick up the file data and supply the correct Content-Type header.

But even when I upload a PDF, the content-type is set to 'text/plain;charset=UTF-8'. I want the content-type to be set to multipart, because this is what the backend expects, but how can I make this happen, if the browser is responsible for setting the content-type?

I have also tried this post's tactic but to no avail. I have also tried using Dropzone.js with the same result.

Here's the code for the request itself:

uploadFile: function(token, baseurl, projectname, filename, file) { 
        var dataUpload= {
          method: 'PUT',
          url: baseurl + '/projects/' + projectname + '/files/' + filename,
          transformRequest: angular.identity,
          headers: {
                  'Authorization': 'bearer ' + token,
                  'Accept': "application/json",
                  'Content-Type': undefined
                },
          data: {
            'files': file
          }
      };
      return dataUpload;
    }

Below I am including the code from the post previously linked which is supposed to work but when I used it with my own url the same thing happens: the browser sets Content-Type to 'text/plain;charset=UTF-8' and I get a 415 error from the backend. How? Why? Any help (including workarounds for the backend) would be extremely appreciated. I've been working on this for days.

The JavaScript:

var myApp = angular.module('myApp', []);

myApp.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]);
            });
        });
    }
 };
}]);

myApp.service('fileUpload', ['$http', function ($http) {
 this.uploadFileToUrl = function(file, uploadUrl){
    var fd = new FormData();
    fd.append('file', file);
    $http.post(uploadUrl, fd, {
        transformRequest: angular.identity,
        headers: {'Content-Type': undefined}
    })
    .success(function(){
    })
    .error(function(){
    });
 }
}]);

myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){

$scope.uploadFile = function(){
    var file = $scope.myFile;
    console.log('file is ' );
    console.dir(file);
    var uploadUrl = "/fileUpload";
    fileUpload.uploadFileToUrl(file, uploadUrl);
};

}]);

The HTML:

<div ng-controller = "myCtrl">
    <input type="file" file-model="myFile"/>
    <button ng-click="uploadFile()">upload me</button>
</div>

Upvotes: 0

Views: 4531

Answers (1)

I guess it's too late to answer this but in case someone came across with the same problem.

The error in your code is here:

data: {
    'files': file
}

Your form data object already has the information of the field your backend is expecting so, you need to change that line for:

data: file

If you've created the FormData object manually you'll probably have something like this:

var fd = new FormData();
fd.append("files", $scope.file);

Upvotes: 1

Related Questions