form data and angularjs multipartform-data multipart

data - Solicitud multiparte con AngularJS



upload file and data angularjs (5)

Tengo un punto final de API al que debo enviar una solicitud HTTP de varias partes, compuesta de dos partes, file (un archivo del sistema de archivos) y data (un objeto JSON).

Después de algunas investigaciones, descubrí cómo hacer una solicitud multiparte en AngularJS:

$http({ method: ''POST'', url: url, headers: { ''Content-Type'': ''multipart/form-data'' }, data: { data: model, file: file }, transformRequest: customFormDataObject });

1) La función customFormDataObject inicialmente tenía esta forma:

customFormDataObject formDataObject = function (data, headersGetter) { var fd = new FormData(); angular.forEach(data, function (value, key) { fd.append(key, value); }); var headers = headersGetter(); delete headers[''Content-Type'']; return fd; };

El resultado de esta implementación es que las partes individuales de la solicitud no tienen un tipo de contentType configurado.

2) Después de leer un poco más ( https://stackoverflow.com/a/24535293/689216 ) traté de usar un Blob para esto, el objeto customFormData ve así (un poco desordenado, básicamente la primera parte será de tipo de contentType application/json , la segunda image/png ):

customFormDataObject = function (data, headersGetter) { var fd = new FormData(); var contentType = ''application/json''; angular.forEach(data, function (value, key) { fd.append(key, new Blob([JSON.stringify(value)], { type: contentType })); contentType = ''image/png''; }); var headers = headersGetter(); delete headers[''Content-Type'']; return fd; };

Este segundo enfoque establece el tipo de contentType correcto para cada parte de la solicitud, pero no establece ningún valor para las partes.

Básicamente, lo que sucede es que con 1) los valores correctos se configuran en los multiparte, pero los contentType no están establecidos. Con 2) se establecen los contentType , pero no los valores para los multiparte.

¿Me estoy perdiendo de algo? ¿Se supone que esta funcionalidad no funciona así?

¡Gracias!


Acabo de resolver exactamente el mismo problema.

Después de algunas pruebas, tuve esta situación que has descrito:

Básicamente, lo que sucede es que con 1) los valores correctos se configuran en las partes múltiples, pero no se establecen los contentType. Con 2) se establecen los contentType, pero no los valores para los multiparte.

Para solucionar este problema, tuve que usar Blob y Post Ajax en lugar de $ http Post .

Parece que $ http no funciona correctamente en este caso.

Código:

var formData = new FormData(); var blobId = new Blob([100], { ''type'':''text/plain'' }); formData.append(''testId'', blobId); var blobImage = fileService.base64ToBlob(contentToDecode, ''image/jpeg''); formData.append(''file'', blobImage, ''imagem'' + (i + 1) + ''.jpg'');

Solicitud:

$.ajax({ url: url, data: formData, cache: false, contentType: false, processData: false, type: ''POST'', success: function(response) { deferred.resolve(response); $rootScope.requestInProgress = false; }, error: function(error) { deferred.reject(error); $rootScope.requestInProgress = false; } });


Has intentado algo como ésto:

$httpProvider.defaults.transformRequest = function(data) { if (data === undefined){ return data; } var formData = new FormData(); for (var key in data){ if(typeof data[key] == ''object'' && !(data[key] instanceof File)){ formData.append(key, JSON.stringify(data[key])); }else{ formData.append(key, data[key]); } } return formData; };


La forma más fácil de subir archivos en Angular:

var fd = new FormData(); fd.append(''file'', file); fd.append(''data'', ''string''); $http.post(uploadUrl, fd, { transformRequest: angular.identity, headers: {''Content-Type'': undefined} }) .success(function(){ }) .error(function(){ });

Absolutamente esenciales son las siguientes dos propiedades del objeto de configuración:

transformRequest: angular.identity

anula la serialización predeterminada de Angular, dejando nuestros datos intactos.

headers: {''Content-Type'': undefined }

permite que el navegador detecte el tipo de Content-Type correcto como multipart/form-data y complete el límite correcto.

¡Nada más me funcionó! Cortesía del maravilloso blog post de Lady Louthan.


Lo que hice para resolver esto fue.

var formData = new FormData(document.getElementById(''myFormId''));

entonces en mi servicio

var deferred = $q.defer(); $http.post(''myurl'', formData, { cache: false, contentType: false, processData: false, }) .success(function (response) { deferred.resolve(response); }) .error(function (reject) { deferred.reject(reject); }); return deferred.promise;


Puede usar https://github.com/danialfarid/ng-file-upload/ .

En este cargador de archivos, hay una disposición para enviar el archivo y los datos (en formato JSON) por separado como mencionó en su pregunta anterior.

Por ejemplo: -

var upload = $upload.upload({ url: url, file: file, method: ''POST'' or ''PUT'', default POST, headers: {''Content-Type'': ''multipart/form-data''}, // only for html5 fileName: ''doc.jpg'', fileFormDataName: ''myFile'', data: {''data'': model} });

En el código anterior, puede enviar una solicitud POST o PUT con ''multipart / form-data'', archivo y objeto de datos como JSON por separado.

Para obtener más información, puede visitar el enlace anterior y consultar el archivo ReadMe.md del complemento.

Sé que mi enfoque es un poco diferente al que está siguiendo actualmente, pero el objetivo es el mismo.