formdata form data angularjs http http-post multipartform-data form-data

angularjs - send formdata angular



Enviar FormData con otro campo en Angular (5)

Tengo un formulario con dos input text y una upload . Tengo que enviarlo al servidor pero tengo algún problema para concatenar el archivo con el texto. El servidor espera esta respuesta:

"title=first_input" "text=second_input" "file=my_file.pdf"

Este es el html :

<input type="text" ng-model="title"> <input type="text" ng-model="text"> <input type="file" file-model="myFile"/> <button ng-click="send()">

Este es el controlador :

$scope.title = null; $scope.text = null; $scope.send = function(){ var file = $scope.myFile; var uploadUrl = ''my_url''; blockUI.start(); Add.uploadFileToUrl(file, $scope.newPost.title, $scope.newPost.text, uploadUrl); };

Este es el archivo de Directiva Modelo:

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

Y este es el Servicio que llama al servidor:

this.uploadFileToUrl = function(file, title, text, uploadUrl){ var fd = new FormData(); fd.append(''file'', file); var obj = { title: title, text: text, file: fd }; var newObj = JSON.stringify(obj); $http.post(uploadUrl, newObj, { transformRequest: angular.identity, headers: {''Content-Type'': ''multipart/form-data''} }) .success(function(){ blockUI.stop(); }) .error(function(error){ toaster.pop(''error'', ''Errore'', error); }); }

Si intento enviar, recibo el error 400, y la respuesta es: Multipart form parse error - Invalid boundary in multipart: None . La carga útil de la solicitud es: {"title":"sadf","text":"sdfsadf","file":{}}


Aquí está la solución completa.

código HTML,

cree el texto y los campos de carga de archivos como se muestra a continuación

<div class="form-group"> <div> <label for="usr">User Name:</label> <input type="text" id="usr" ng-model="model.username"> </div> <div> <label for="pwd">Password:</label> <input type="password" id="pwd" ng-model="model.password"> </div><hr> <div> <div class="col-lg-6"> <input type="file" file-model="model.somefile"/> </div> </div> <div> <label for="dob">Dob:</label> <input type="date" id="dob" ng-model="model.dob"> </div> <div> <label for="email">Email:</label> <input type="email"id="email" ng-model="model.email"> </div> <button type="submit" ng-click="saveData(model)" >Submit</button>

código directivo

crear una directiva de modelo de archivo para analizar el archivo

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

Código de servicio

agregue el archivo y los campos para formar datos y haga $ http.post como se muestra a continuación recuerde mantener ''Content-Type'': undefined

.service(''fileUploadService'', [''$http'', function ($http) { this.uploadFileToUrl = function(file, username, password, dob, email, uploadUrl){ var myFormData = new FormData(); myFormData.append(''file'', file); myFormData.append(''username'', username); myFormData.append(''password'', password); myFormData.append(''dob'', dob); myFormData.append(''email'', email); $http.post(uploadUrl, myFormData, { transformRequest: angular.identity, headers: {''Content-Type'': undefined} }) .success(function(){ }) .error(function(){ }); } }]);

En el controlador

Ahora en el controlador, llame al servicio enviando los datos necesarios para que se agreguen en los parámetros,

$scope.saveData = function(model){ var file = model.myFile; var uploadUrl = "/api/createUsers"; fileUpload.uploadFileToUrl(file, model.username, model.password, model.dob, model.email, uploadUrl); };


Estás enviando datos con formato JSON a un servidor que no espera ese formato. Ya proporcionó el formato que necesita el servidor, por lo que deberá formatearlo usted mismo, lo cual es bastante simple.

var data = ''"title=''+title+''" "text=''+text+''" "file=''+file+''"''; $http.post(uploadUrl, data)


Esto nunca va a funcionar, no puedes encadenar tu objeto FormData.

Usted debe hacer esto:

this.uploadFileToUrl = function(file, title, text, uploadUrl){ var fd = new FormData(); fd.append(''title'', title); fd.append(''text'', text); fd.append(''file'', file); $http.post(uploadUrl, obj, { transformRequest: angular.identity, headers: {''Content-Type'': undefined} }) .success(function(){ blockUI.stop(); }) .error(function(error){ toaster.pop(''error'', ''Errore'', error); }); }


No FormData con POST en el servidor. Hacer esto:

this.uploadFileToUrl = function(file, title, text, uploadUrl){ var payload = new FormData(); payload.append("title", title); payload.append(''text'', text); payload.append(''file'', file); return $http({ url: uploadUrl, method: ''POST'', data: payload, //assign content-type as undefined, the browser //will assign the correct boundary for us headers: { ''Content-Type'': undefined}, //prevents serializing payload. don''t do it. transformRequest: angular.identity }); }

Entonces úsalo:

MyService.uploadFileToUrl(file, title, text, uploadUrl).then(successCallback).catch(errorCallback);


Usando $resource en AngularJS puedes hacer:

task.service.js

$ngTask.factory("$taskService", [ "$resource", function ($resource) { var taskModelUrl = ''api/task/''; return { rest: { taskUpload: $resource(taskModelUrl, { id: ''@id'' }, { save: { method: "POST", isArray: false, headers: {"Content-Type": undefined}, transformRequest: angular.identity } }) } }; } ]);

Y luego úsalo en un módulo:

task.module.js

$ngModelTask.controller("taskController", [ "$scope", "$taskService", function ( $scope, $taskService, ) { $scope.saveTask = function (name, file) { var newTask, payload = new FormData(); payload.append("name", name); payload.append("file", file); newTask = $taskService.rest.taskUpload.save(payload); // check if exists } }