0

Updated:

I'm facing 405 error upon uploading multiple files (images) via multipart/data-form. I'm able to send images in request and seems my payload showing correct boundries. But I'm getting empty response 405 on submit of API and response.status is showing 405 (method not allowed) error. I'm wondering what could be wrong as everything seems fine.

However i do suspect that there might be something to do with boundries in request-payload. I also come to know that browsers change MIME-TYPE when uploading and this conflicts with multipart/formData.

Please advise what could be wrong. Below is my code.

Directive (file-upload)

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

        }
    };
}]);

View (html)

<form ng-submit="submit()">
    <input type="text" ng-model="for-param">
    <input type="text" ng-model="for-param">
    <input type="text" ng-model="for-param">

    <input type="file" file-model="image01">
    <input type="file" file-model="image02">

    <button type="submit">Save</button>
</form>

Controller (on-submit)

$scope.submit = function () {
    var params = {...};
    var data = {
        'frond-side-image' : $scope.image01,
        'back-side-image': $scope.image02
    };

    var formData = new $window.FormData();
    formData.append("image01", $scope.image01);
    formData.append("image02", $scope.image02);

    // Service
    $http({
        method: "POST",
        url: "api-url",
        headers: { "Content-Type": undefined },
        params: params,
        data: formData
    }).then(function (response) {
        console.log(response);
    }, function (error) {
        console.log(error);
    });
};

Based on above config, following is my request & response

Header Request (after submit)

Content-Type: multipart/form-data; boundary=…--------------147472608521363

Request Payload

-----------------------------1363509831949
Content-Disposition: form-data; name="image01"

stacked_circles.png
-----------------------------1363509831949
Content-Disposition: form-data; name="image01"

stacked_circles.png
-----------------------------1363509831949--

Response

Based on above config I'm getting empty response, but I'm do getting 405 error which is method not allowed.

Please note that later on I'll convert image to base64 to upload on AWS (I'll just post image/base64 to backend than backend will upload it to AWS).


I've created JSFIDDLE for particular query.

Umair Dev
  • 31
  • 5

1 Answers1

0

Append the two images to the FormData object:

$scope.submit = function () {
    var params = {};
    var formData = new $window.FormData();
    ̶f̶o̶r̶m̶D̶a̶t̶a̶.̶a̶p̶p̶e̶n̶d̶(̶"̶f̶i̶l̶e̶"̶,̶ ̶d̶a̶t̶a̶)̶;̶
    formData.append("file01", $scope.image01);
    formData.append("file02", $scope.image02);

    // Service
    $http({
        method: "POST",
        url: "api-url",
        headers: { "Content-Type": undefined },
        params: params,
        data: formData
    }).then(function (response) {
        console.log(response);
    }, function (error) {
        console.log(error);
    });
};

When sending files, each file needs its own formData.append call.


Be sure to use the single file version of the file-model directive:

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(){
                    ̶m̶o̶d̶e̶l̶S̶e̶t̶t̶e̶r̶(̶s̶c̶o̶p̶e̶,̶ ̶e̶l̶e̶m̶e̶n̶t̶[̶0̶]̶.̶f̶i̶l̶e̶s̶)̶;̶
                    modelSetter(scope, element[0].files[0]);
                });
            });

        }
    };
}]);
<form ng-submit="submit()">
    <input type="file" file-model="image01">
    <input type="file" file-model="image02">

    <button type="submit">Save</button>
</form>
georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • Thanks for helping me out on this one. – Umair Dev Mar 07 '19 at 18:03
  • Now I'm able to show multiple files in **Request Payload** but I'm getting **405 Error** (method not allowed). I also think i need to add keys for each form-data image that I'm sending as multipart, cause I've this in postman and both these has specific keys added to it. I think for assigning key to each image, i need to replace **"file01"** `formData.append("file01", $scope.image01)` with specific field. Please confirm if this is the right appraoch. – Umair Dev Mar 07 '19 at 18:16
  • One more thing that i need confirmation. If i append image object (`$scope.image01`) than it shows strange-long text/string on particular image in **request-payload**. But if i add **name** (`$scope.image01.name`) at the end object than only image name gets printed out in **request-payload**. I'm wondering which is right to choose. – Umair Dev Mar 07 '19 at 18:20
  • Looks like my **Request Payload** is generating fine, but I'm still getting **405 (Method not allowed) error**. Also in **console** I'm getting **XML Parsing Error: no root element found** What could be wrong please help, as this thing is becoming headache ;( – Umair Dev Mar 08 '19 at 07:52