AngularJS Carga varios archivos con la API FormData

Necesito subir archivos de imagen y video al servidor en una aplicación angular usando Laravel 5.1 como back-end. Todas las solicitudes de Ajax deben ir primero al controlador de Laravel, y tenemos el código allí para saber cómo se maneja el archivo cuando llega. Anteriormente, hemos hecho formularios HTML normales para enviar las cargas de archivos al controlador, pero en este caso debemos evitar la actualización de la página de un formulario, así que estoy intentando hacerlo en Ajax a través de Angular.

¿Qué información debo enviar al controlador Laravel con Ajax que estaba siendo enviado al controlador a través de un formulario HTML previamente?

Este es el código en el controlador de Laravel que manejó la información del archivo una vez que llegó allí. Eso es lo que necesito saber cómo enviar, así que espero poder volver a utilizar este código:

$promotion = Promotion::find($id); if (Input::hasFile('img_path')){ $path = public_path().'/images/promotion/'.$id.'/'; $file_path = $path.'promotion.png'; $delete = File::delete($file_path); $file = Input::file('img_path'); $uploadSuccess = $file->move($path, 'promotion.png'); $promotion->img_path = '/images/promotion/'.$id.'/promotion.png'; } if (Input::hasFile('video_path')){ $path = public_path().'/video/promotion/'.$id.'/'; $file_path = $path.'promotion.mp4'; $delete = File::delete($file_path); $file = Input::file('video_path'); $uploadSuccess = $file->move($path, 'promotion.mp4'); $promotion->video_path = '/video/promotion/'.$id.'/promotion.mp4'; } 

Como puede ver arriba, estamos convirtiendo cualquier archivo que obtengamos en un archivo PNG con el nombre de archivo promotion.png, por lo que es fácil de obtener, y solo aceptamos el formato de video .mp4. Por eso, no tenemos que preocuparnos por verificar si el archivo existe y está bien sobreescribirlo. Es por eso que puede ver en el código que eliminamos cualquier archivo existente de ese nombre antes de guardarlo.

El HTML era solo una entrada con un tipo de “archivo”:

  

Estamos usando Angular ahora, así que ya no puedo enviar lo anterior a través de un formulario HTML. Eso es lo que necesito saber cómo hacer.

Somos dos desarrolladores que hacemos nuestro mejor esfuerzo, por lo que estoy seguro de que hay una mejor manera de hacerlo. Sin embargo, antes de refactorizar todo esto, espero poder utilizar Angular (o jQuery como último recurso) para enviar al controlador los datos de archivo que Laravel necesita para que el código anterior funcione. La respuesta puede ser tan simple como “enviar un PUT al método en ese controlador anterior, pero en lugar de una carga útil JSON normal, use la información del archivo en este formato y puede recostackr esa información con …”

También agradecería cualquier consejo sobre mejores formas de hacerlo en el futuro.

Cómo PUBLICAR FormData utilizando el servicio $ http

Al usar la API FormData para POST archivos y datos, es importante establecer el encabezado Content-Type en undefined .

 var fd = new FormData() for (var i in $scope.files) { fd.append("fileToUpload", $scope.files[i]); } var config = {headers: {'Content-Type': undefined}}; var httpPromise = $http.post(url, fd, config); 

Por defecto, el framework AngularJS utiliza el tipo de contenido application/json . Al configurar Content-Type: undefined , AngularJS framework omite el encabezado de tipo de contenido que permite a la API XHR establecer el tipo de contenido. Al enviar un objeto FormData , la API XHR establece el tipo de contenido en multipart/form-data con los límites adecuados y la encoding base64 .

Para obtener más información, consulte Referencia de MDN Web API – Método de envío XHR


¿Cómo $scope.files información del archivo en $scope.files ?

Cómo habilitar para trabajar con ng-model

Esta directiva también permite que trabaje automáticamente con las directivas ng-change y ng-form .

 angular.module("app",[]); angular.module("app").directive("selectFilesNg", function() { return { require: "ngModel", link: function postLink(scope,elem,attrs,ngModel) { elem.on("change", function(e) { var files = elem[0].files; ngModel.$setViewValue(files); }) } } }); 
   

AngularJS Input `type=file` Demo

NameDateSizeType
{{file.name}} {{file.lastModified | date : 'MMMdd,yyyy'}} {{file.size}} {{file.type}}