Carga de archivos usando AngularJS

296

Aquí está mi formulario HTML:

<form name="myForm" ng-submit="">
    <input ng-model='file' type="file"/>
    <input type="submit" value='Submit'/>
</form>

Quiero cargar una imagen de la máquina local y quiero leer el contenido del archivo cargado. Todo esto lo quiero hacer usando AngularJS.

Cuando trato de imprimir el valor $scope.fileviene como indefinido.

Aditya Sethi
fuente

Respuestas:

344

Algunas de las respuestas aquí proponen el uso FormData(), pero desafortunadamente es un objeto del navegador que no está disponible en Internet Explorer 9 y versiones posteriores. Si necesita admitir esos navegadores antiguos, necesitará una estrategia de copia de seguridad como usar <iframe>o Flash.

Ya hay muchos módulos Angular.js para realizar la carga de archivos. Estos dos tienen soporte explícito para navegadores antiguos:

Y algunas otras opciones:

Uno de estos debe ajustarse a su proyecto, o puede darle una idea de cómo codificarlo usted mismo.

Anoyz
fuente
44
Una solución más (IaaS para cargar archivos): github.com/uploadcare/angular-uploadcare
David Avsajanishvili
27
EggHead tiene un buen video sobre esto - egghead.io/lessons/angularjs-file-uploads
Adam Zerner
2
danialfarid / angular-file-upload se renombra a ng-file-upload
Michael
55
Respuesta de 3 años. IE 9 está MUERTO ahora en 2016.
user2404597
55
Creo que debería actualizar su respuesta para tener una solución adecuada en lugar de señalar enlaces. Esa es la forma de desbordamiento de pila. De lo contrario, solo hazlo como un comentario.
Alex Reynolds
178

Lo más fácil es usar la API HTML5, es decir FileReader

HTML es bastante sencillo:

<input type="file" id="file" name="file"/>
<button ng-click="add()">Add</button>

En su controlador, defina el método 'agregar':

$scope.add = function() {
    var f = document.getElementById('file').files[0],
        r = new FileReader();

    r.onloadend = function(e) {
      var data = e.target.result;
      //send your binary data via $http or $resource or do anything else with it
    }

    r.readAsBinaryString(f);
}

Compatibilidad del navegador

Navegadores de escritorio

Edge 12, Firefox (Gecko) 3.6 (1.9.2), Chrome 7, Opera * 12.02, Safari 6.0.2

Navegadores móviles

Firefox (Gecko) 32, Chrome 3, Opera * 11.5, Safari 6.1

Nota: el método readAsBinaryString () está en desuso y se debe usar readAsArrayBuffer () en su lugar.

yagger
fuente
10
FileReader es una clase de la API de archivos HTML5 estándar w3.org/TR/FileAPI . Le permite leer datos del archivo especificado en el elemento de entrada html y procesarlos dentro de la onloadendfunción de devolución de llamada. No necesita ninguna biblioteca para usar esta API, ya está en su navegador (a menos que use una muy antigua). Espero que esto ayude.
yagger
15
FileReader.readAsBinaryString está en desuso a partir del 12 de julio de 2012 Borrador de trabajo del W3C.
Shane Stillwell
13
No deberías acceder a DOM con angular. Es una muy mala práctica.
jeanmatthieud
99
@Siderex, no en el controlador, pero es genial hacerlo desde la directiva. De hecho, para eso están las directivas. Puede leerlo en Angular docs docs.angularjs.org/guide/directive
yagger
1
@yagger, ¿hay alguna razón particular por la cual sus enlaces hacen referencia al readAsArrayBuffermétodo de FileReaderSync (que solo está disponible en los trabajadores web) en lugar de la API asíncrona normal de FileReader ?
doldt
58

Esta es la forma moderna del navegador, sin bibliotecas de terceros. Funciona en todos los últimos navegadores.

 app.directive('myDirective', function (httpPostFactory) {
    return {
        restrict: 'A',
        scope: true,
        link: function (scope, element, attr) {

            element.bind('change', function () {
                var formData = new FormData();
                formData.append('file', element[0].files[0]);
                httpPostFactory('upload_image.php', formData, function (callback) {
                   // recieve image name to use in a ng-src 
                    console.log(callback);
                });
            });

        }
    };
});

app.factory('httpPostFactory', function ($http) {
    return function (file, data, callback) {
        $http({
            url: file,
            method: "POST",
            data: data,
            headers: {'Content-Type': undefined}
        }).success(function (response) {
            callback(response);
        });
    };
});

HTML:

<input data-my-Directive type="file" name="file">

PHP:

if (isset($_FILES['file']) && $_FILES['file']['error'] == 0) {

// uploads image in the folder images
    $temp = explode(".", $_FILES["file"]["name"]);
    $newfilename = substr(md5(time()), 0, 10) . '.' . end($temp);
    move_uploaded_file($_FILES['file']['tmp_name'], 'images/' . $newfilename);

// give callback to your angular code with the image src name
    echo json_encode($newfilename);
}

js fiddle (solo front-end) https://jsfiddle.net/vince123/8d18tsey/31/

Vince Verhoeven
fuente
¿Cómo buscarías el archivo en el nodo?
Jugoso
¿Más detalles? ¿Necesita una ng-submito una acción de formulario? Esto por sí solo no hace nada
Aron
@Emaborsa hola Agregué un jsfiddle e hice un ejemplo de código php más completo. Envía la imagen después de que el valor de la entrada del archivo ha cambiado, por lo que no se requiere ng-submit.
Vince Verhoeven el
La solución más simple y perfecta, pero me llevó años averiguar cómo hacer que mis servicios WCF hagan frente a los datos que se estaban cargando. Es vital que tome el flujo de datos y lo pase a través de algo como MultiParser para leer realmente los datos del archivo: stackoverflow.com/a/23702692/391605 De lo contrario, almacenará bytes sin formato de "------ WebKitFormBoundary Disposición de contenido: ... etc. "
Mike Gledhill
Necesitaba agregar la propiedad 'transformRequest: angular.identity' al objeto de solicitud $ http como lo muestra Manoy Ojha un poco más abajo; de lo contrario, Content-Type no se establecería correctamente y el ejemplo no funcionaría.
Gregor Slavec
38

A continuación se muestra un ejemplo funcional de carga de archivos:

http://jsfiddle.net/vishalvasani/4hqVu/

En esta función llamada

setFiles

Desde la vista, que actualizará la matriz de archivos en el controlador

o

Puede verificar la carga de archivos jQuery usando AngularJS

http://blueimp.github.io/jQuery-File-Upload/angularjs.html

JQuery Guru
fuente
Hola, estaba buscando algo a través del cual puedo subir un archivo y mostrarlo debajo de él. Sin embargo, en su ejemplo, no pude hacer lo mismo. No importa, pero soy nuevo en este angularjs y mi intención de aprender a hacer este objetivo en particular de una manera más simple pero robusta.
Aditya Sethi
Esto ayudó mucho. ¡Gracias!
RachelD
Excelente ejemplo sin usar una biblioteca / extensión adicional. Gracias.
markdsievers 05 de
44
Muy útil, solo una nota ... esto usa File API que no funciona en IE9 o inferior.
ArjaaAine
¿Alguna idea de cómo obtengo errores del resultado? El servidor puede generar un error y me gustaría mostrar ese mensaje de error ...
CularBytes
17

Puede lograr una buena carga de archivos y carpetas usando flow.js .

https://github.com/flowjs/ng-flow

Mira una demostración aquí

http://flowjs.github.io/ng-flow/

No es compatible con IE7, IE8, IE9, por lo que eventualmente tendrá que usar una capa de compatibilidad

https://github.com/flowjs/fusty-flow.js

Fizer Khan
fuente
`flow.js 'es fantástico, pero todavía tiene poca documentación. Necesito manipular una sola carga y agregar una vista previa y también enviar un botón de evento separado, pero no sé cómo hacerlo.
Francis Rodrigues
14

Use el onchangeevento para pasar el elemento del archivo de entrada a su función.

<input type="file" onchange="angular.element(this).scope().fileSelected(this)" />

Entonces, cuando un usuario selecciona un archivo, tiene una referencia a él sin que el usuario tenga que hacer clic en el botón "Agregar" o "Cargar".

$scope.fileSelected = function (element) {
    var myFileSelected = element.files[0];
};
James Lawruk
fuente
2
Esto no funciona como se desea. Este es mi flujo de trabajo: 1. Actualizar la página 2. Agregar nuevo archivo. ** El primer archivo agregado siempre está indefinido. ** 3. Agregue otro archivo. De ahora en adelante, cada archivo cargado es el archivo anterior que agregué. Entonces, para el segundo archivo que agrego, esto cargaría el primer archivo que agregué (que realmente falló)
Pulkit Pahwa
1
El mejor método!
Stepan Yakovenko
11

Probé todas las alternativas que @Anoyz (respuesta correcta) ofrece ... y la mejor solución es https://github.com/danialfarid/angular-file-upload

Algunas caracteristicas:

  • Progreso
  • Multifiles
  • Campos
  • Navegadores antiguos (IE8-9)

Me funciona bien. Solo tienes que prestar atención a las instrucciones.

En el lado del servidor, uso NodeJs, Express 4 y el middleware Multer para gestionar la solicitud de varias partes.

Javier Cornejo Alfaro
fuente
¿Cómo se muestran las imágenes? Desde el backend, ingresan con éxito, pero se guardan como nlzt9LJWRrAZEO3ZteZUOgGcpero sin el formato .png. ¿Cómo agregar eso?
Saras Arya
9

HTML

<html>
    <head></head>

<body ng-app = "myApp">

  <form ng-controller = "myCtrl">
     <input type = "file" file-model="files" multiple/>
     <button ng-click = "uploadFile()">upload me</button>
     <li ng-repeat="file in files">{{file.name}}</li>
  </form>

Guiones

  <script src = 
     "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
  <script>
    angular.module('myApp', []).directive('fileModel', ['$parse', function ($parse) {
        return {
           restrict: 'A',
           link: function(scope, element, attrs) {
              element.bind('change', function(){
              $parse(attrs.fileModel).assign(scope,element[0].files)
                 scope.$apply();
              });
           }
        };
     }]).controller('myCtrl', ['$scope', '$http', function($scope, $http){


       $scope.uploadFile=function(){
       var fd=new FormData();
        console.log($scope.files);
        angular.forEach($scope.files,function(file){
        fd.append('file',file);
        });
       $http.post('http://localhost:1337/mediaobject/upload',fd,
           {
               transformRequest: angular.identity,
               headers: {'Content-Type': undefined}                     
            }).success(function(d)
                {
                    console.log(d);
                })         
       }
     }]);

  </script>

Manoj Ojha
fuente
9

El <input type=file>elemento no funciona por defecto con la directiva ng-model . Necesita una directiva personalizada :

Demostración de trabajo de la select-ng-filesdirectiva que funciona con ng-model1

angular.module("app",[]);

angular.module("app").directive("selectNgFiles", function() {
  return {
    require: "ngModel",
    link: function postLink(scope,elem,attrs,ngModel) {
      elem.on("change", function(e) {
        var files = elem[0].files;
        ngModel.$setViewValue(files);
      })
    }
  }
});
<script src="//unpkg.com/angular/angular.js"></script>
  <body ng-app="app">
    <h1>AngularJS Input `type=file` Demo</h1>
    
    <input type="file" select-ng-files ng-model="fileList" multiple>
    
    <h2>Files</h2>
    <div ng-repeat="file in fileList">
      {{file.name}}
    </div>
  </body>


$http.postde una FileList

$scope.upload = function(url, fileList) {
    var config = { headers: { 'Content-Type': undefined },
                   transformResponse: angular.identity
                 };
    var promises = fileList.map(function(file) {
        return $http.post(url, file, config);
    });
    return $q.all(promises);
};

Al enviar una POST con un objeto File , es importante configurarlo 'Content-Type': undefined. El método de envío XHR detectará el objeto Archivo y establecerá automáticamente el tipo de contenido.

georgeawg
fuente
7

Fácil con una directiva

HTML:

<input type="file" file-upload multiple/>

JS:

app.directive('fileUpload', function () {
return {
    scope: true,        //create a new scope
    link: function (scope, el, attrs) {
        el.bind('change', function (event) {
            var files = event.target.files;
            //iterate files since 'multiple' may be specified on the element
            for (var i = 0;i<files.length;i++) {
                //emit event upward
                scope.$emit("fileSelected", { file: files[i] });
            }                                       
        });
    }
};

En la directiva nos aseguramos de que se cree un nuevo ámbito y luego escuchamos los cambios realizados en el elemento de entrada del archivo. Cuando se detectan cambios con emitir un evento a todos los ámbitos ancestros (hacia arriba) con el objeto de archivo como parámetro.

En tu controlador:

$scope.files = [];

//listen for the file selected event
$scope.$on("fileSelected", function (event, args) {
    $scope.$apply(function () {            
        //add the file object to the scope's files collection
        $scope.files.push(args.file);
    });
});

Luego, en su llamada ajax:

data: { model: $scope.model, files: $scope.files }

http://shazwazza.com/post/uploading-files-and-json-data-in-the-same-request-with-angular-js/

Asher
fuente
7

Creo que esta es la carga angular del archivo:

ng-file-upload

Directiva ligera JS angular para cargar archivos.

Aquí está la página DEMO .

  • Admite progreso de carga, cancelar / cancelar carga mientras está en progreso, arrastrar y soltar archivos (html5), arrastrar y soltar directorios (webkit), métodos CORS, PUT (html5) / POST, validación del tipo y tamaño de archivo, muestra una vista previa de las imágenes seleccionadas / audio / videos.
  • Carga cruzada de archivos del navegador y FileReader (HTML5 y no HTML5) con Flash polyfill FileAPI. Permite la validación / modificación del lado del cliente antes de cargar el archivo
  • Carga directa a los servicios de db CouchDB, imgur, etc ... con el tipo de contenido del archivo usando Upload.http (). Esto habilita el evento de progreso para solicitudes angulares de POST / PUT http.
  • Separa el archivo shim, los archivos FileAPI se cargan a pedido para el código no HTML5, lo que significa que no hay carga / código adicional si solo necesita soporte HTML5.
  • Ligero usando $ http regular para cargar (con shim para navegadores que no son HTML5) para que todas las características angulares $ http estén disponibles

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

Mohamad Shiralizadeh
fuente
6

Su archivo y datos json se cargan al mismo tiempo.

// FIRST SOLUTION
 var _post = function (file, jsonData) {
            $http({
                url: your url,
                method: "POST",
                headers: { 'Content-Type': undefined },
                transformRequest: function (data) {
                    var formData = new FormData();
                    formData.append("model", angular.toJson(data.model));
                    formData.append("file", data.files);
                    return formData;
                },
                data: { model: jsonData, files: file }
            }).then(function (response) {
                ;
            });
        }
// END OF FIRST SOLUTION

// SECOND SOLUTION
// If you can add plural file and  If above code give an error.
// You can try following code
 var _post = function (file, jsonData) {
            $http({
                url: your url,
                method: "POST",
                headers: { 'Content-Type': undefined },
                transformRequest: function (data) {
                    var formData = new FormData();
                    formData.append("model", angular.toJson(data.model));
                for (var i = 0; i < data.files.length; i++) {
                    // add each file to
                    // the form data and iteratively name them
                    formData.append("file" + i, data.files[i]);
                }
                    return formData;
                },
                data: { model: jsonData, files: file }
            }).then(function (response) {
                ;
            });
        }
// END OF SECOND SOLUTION

barış çıracı
fuente
4

Puede usar un FormDataobjeto que sea seguro y rápido:

// Store the file object when input field is changed
$scope.contentChanged = function(event){
    if (!event.files.length)
        return null;

    $scope.content = new FormData();
    $scope.content.append('fileUpload', event.files[0]); 
    $scope.$apply();
}

// Upload the file over HTTP
$scope.upload = function(){
    $http({
        method: 'POST', 
        url: '/remote/url',
        headers: {'Content-Type': undefined },
        data: $scope.content,
    }).success(function(response) {
        // Uploading complete
        console.log('Request finished', response);
    });
}
Farsheed
fuente
¿Puede explicar también dónde se usa exactamente 'contentChanged'?
Marc J. Schmidt
Cuando cambia la entrada de un archivo, al activar esta función comenzará el proceso de carga.
Farsheed
1
Como no hay <input type="file" ng-change="contentChanged($event)">, ¿cómo hacerlo?
Marc J. Schmidt
3

http://jsfiddle.net/vishalvasani/4hqVu/ funciona bien en Chrome e IE (si actualiza CSS un poco en la imagen de fondo). Esto se usa para actualizar la barra de progreso:

 scope.progress = Math.round(evt.loaded * 100 / evt.total)

pero en FireFox los datos [porcentuales] de angular no se actualizan correctamente en DOM, aunque los archivos se cargan correctamente.

mayankcpdixit
fuente
Para FF, puede escuchar el loadevento y, si la longitud es computable, dispare un evento de progreso para indicar la carga exitosa. github.com/danialfarid/angular-file-upload ya se encarga de eso.
danial
Está allí, pero en el violín dado también se verifica y aplica. Todavía no hay esperanza en FF.
mayankcpdixit
Creo que si solo llamas a uploadProgress dentro de uploadComplete, debería funcionar para FF
danial
NO, no lo hace, e incluso si lo hace, ¿puede explicar por qué? He dado un enlace para violín en mi publicación. Si es posible, ¿puede actualizarlo para trabajar en FF y comentar el enlace de la solución aquí?
mayankcpdixit
¿Qué versión de Firefox?
danial
3

Puede considerar IaaS para la carga de archivos, como Uploadcare . Hay un paquete angular para ello: https://github.com/uploadcare/angular-uploadcare

Técnicamente se implementa como una directiva, que proporciona diferentes opciones para cargar y manipulaciones para las imágenes cargadas dentro del widget:

<uploadcare-widget
  ng-model="object.image.info.uuid"
  data-public-key="YOURKEYHERE"
  data-locale="en"
  data-tabs="file url"
  data-images-only="true"
  data-path-value="true"
  data-preview-step="true"
  data-clearable="true"
  data-multiple="false"
  data-crop="400:200"
  on-upload-complete="onUCUploadComplete(info)"
  on-widget-ready="onUCWidgetReady(widget)"
  value="{{ object.image.info.cdnUrl }}"
 />

Más opciones de configuración para jugar: https://uploadcare.com/widget/configure/

David Avsajanishvili
fuente
3

Sé que es una entrada tardía, pero he creado una directiva de carga simple. ¡Lo que puedes conseguir trabajando en poco tiempo!

<input type="file" multiple ng-simple-upload web-api-url="/api/Upload" callback-fn="myCallback" />

ng-simple-upload más en Github con un ejemplo usando API web.

shammelburg
fuente
3

HTML

<input type="file" id="file" name='file' onchange="angular.element(this).scope().profileimage(this)" />

agregue el método 'profileimage ()' a su controlador

    $scope.profileimage = function(selectimage) {
      console.log(selectimage.files[0]);
 var selectfile=selectimage.files[0];
        r = new FileReader();
        r.onloadend = function (e) {
            debugger;
            var data = e.target.result;

        }
        r.readAsBinaryString(selectfile);
    }
Lakmi
fuente
2

Esto debería ser una actualización / comentario a la respuesta de @ jquery-guru, pero como no tengo suficiente representante, irá aquí. Soluciona los errores que ahora genera el código.

https://jsfiddle.net/vzhrqotw/

El cambio es básicamente:

FileUploadCtrl.$inject = ['$scope']
function FileUploadCtrl(scope) {

A:

app.controller('FileUploadCtrl', function($scope)
{

Siéntase libre de moverse a un lugar más apropiado si lo desea.

SKR
fuente
2

He leído todo el hilo y la solución API HTML5 se ve mejor. Pero cambia mis archivos binarios y los corrompe de una manera que no he investigado. La solución que funcionó perfectamente para mí fue:

HTML:

<input type="file" id="msds" ng-model="msds" name="msds"/>
<button ng-click="msds_update()">
    Upload
</button>

JS:

msds_update = function() {
    var f = document.getElementById('msds').files[0],
        r = new FileReader();
    r.onloadend = function(e) {
        var data = e.target.result;
        console.log(data);
        var fd = new FormData();
        fd.append('file', data);
        fd.append('file_name', f.name);
        $http.post('server_handler.php', fd, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        })
        .success(function(){
            console.log('success');
        })
        .error(function(){
            console.log('error');
        });
    };
    r.readAsDataURL(f);
}

Lado del servidor (PHP):

$file_content = $_POST['file'];
$file_content = substr($file_content,
    strlen('data:text/plain;base64,'));
$file_content = base64_decode($file_content);
Camille Sauvage
fuente
1

Puedo cargar archivos usando AngularJS usando el siguiente código:

El fileargumento por el que se debe pasar para la función ngUploadFileUploades$scope.file según su pregunta.

El punto clave aquí es usar transformRequest: []. Esto evitará que $ http se enrede con el contenido del archivo.

       function getFileBuffer(file) {
            var deferred = new $q.defer();
            var reader = new FileReader();
            reader.onloadend = function (e) {
                deferred.resolve(e.target.result);
            }
            reader.onerror = function (e) {
                deferred.reject(e.target.error);
            }

            reader.readAsArrayBuffer(file);
            return deferred.promise;
        }

        function ngUploadFileUpload(endPointUrl, file) {

            var deferred = new $q.defer();
            getFileBuffer(file).then(function (arrayBuffer) {

                $http({
                    method: 'POST',
                    url: endPointUrl,
                    headers: {
                        "accept": "application/json;odata=verbose",
                        'X-RequestDigest': spContext.securityValidation,
                        "content-length": arrayBuffer.byteLength
                    },
                    data: arrayBuffer,
                    transformRequest: []
                }).then(function (data) {
                    deferred.resolve(data);
                }, function (error) {
                    deferred.reject(error);
                    console.error("Error", error)
                });
            }, function (error) {
                console.error("Error", error)
            });

            return deferred.promise;

        }
Karthik
fuente
0

La respuesta aceptada arriba no es compatible con el navegador. Si alguien tiene un problema de compatibilidad, intente esto.

Violín

Ver código

 <div ng-controller="MyCtrl">
      <input type="file" id="file" name="file"/>
      <br>
      <button ng-click="add()">Add</button>
      <p>{{data}}</p>
    </div>

Código del controlador

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

function MyCtrl($scope) {
    $scope.data = 'none';    
    $scope.add = function(){
      var f = document.getElementById('file').files[0],
          r = new FileReader();
      r.onloadend = function(e){        
          var binary = "";
var bytes = new Uint8Array(e.target.result);
var length = bytes.byteLength;

for (var i = 0; i < length; i++) 
{
    binary += String.fromCharCode(bytes[i]);
}

$scope.data = (binary).toString();

          alert($scope.data);
      }
      r.readAsArrayBuffer(f);
    }
}
Kurkula
fuente
0

en palabras simples

en HTML: agregue solo el siguiente código

     <form name="upload" class="form" data-ng-submit="addFile()">
  <input type="file" name="file" multiple 
 onchange="angular.element(this).scope().uploadedFile(this)" />
 <button type="submit">Upload </button>
</form>

en el controlador : se llama a esta función cuando hace clic en " botón cargar archivo" . cargará el archivo. Puedes consolarlo.

$scope.uploadedFile = function(element) {
$scope.$apply(function($scope) {
  $scope.files = element.files;         
});
}

agregue más en los controladores : a continuación, agregue el código a la función. Esta función se llama cuando hace clic en el botón que se usa "golpear la API (POST)" . enviará el archivo (que cargó) y los datos del formulario al backend.

var url = httpURL + "/reporttojson"
        var files=$scope.files;

         for ( var i = 0; i < files.length; i++)
         {
            var fd = new FormData();
             angular.forEach(files,function(file){
             fd.append('file',file);
             });
             var data ={
              msg : message,
              sub : sub,
              sendMail: sendMail,
              selectUsersAcknowledge:false
             };

             fd.append("data", JSON.stringify(data));
              $http.post(url, fd, {
               withCredentials : false,
               headers : {
                'Content-Type' : undefined
               },
             transformRequest : angular.identity
             }).success(function(data)
             {
                  toastr.success("Notification sent successfully","",{timeOut: 2000});
                  $scope.removereport()
                   $timeout(function() {
                    location.reload();
                }, 1000);

             }).error(function(data)
             {
              toastr.success("Error in Sending Notification","",{timeOut: 2000});
              $scope.removereport()
             });
        }

en este caso ... agregué el siguiente código como datos del formulario

var data ={
          msg : message,
          sub : sub,
          sendMail: sendMail,
          selectUsersAcknowledge:false
         };
Shashwat Gupta
fuente
0
<form id="csv_file_form" ng-submit="submit_import_csv()" method="POST" enctype="multipart/form-data">
    <input ng-model='file' type="file"/>
    <input type="submit" value='Submit'/>
</form>

En el controlador angularJS

$scope.submit_import_csv = function(){

        var formData = new FormData(document.getElementById("csv_file_form"));
        console.log(formData);

        $.ajax({
            url: "import",
            type: 'POST',
            data:  formData,
            mimeType:"multipart/form-data",
            contentType: false,
            cache: false,
            processData:false,
            success: function(result, textStatus, jqXHR)
            {
            console.log(result);
            }
        });

        return false;
    }
rubyshine72
fuente
0

Hemos utilizado HTML, CSS y AngularJS. El siguiente ejemplo muestra cómo cargar el archivo usando AngularJS.

<html>

   <head>
      <script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
   </head>

   <body ng-app = "myApp">

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

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

      </script>

   </body>
</html>
Jignesh Mesvaniya
fuente
Esto proviene de TutorialsPoint , pero al menos hiciste el buen trabajo de corregir su ejemplo, ¡que ni siquiera se puede ejecutar debido a errores obvios!
Benito
0

Ejemplo de trabajo usando Directiva simple ( ng-file-model ):

.directive("ngFileModel", [function () {
  return {
      $scope: {
          ngFileModel: "="
      },
      link: function ($scope:any, element, attributes) {
          element.bind("change", function (changeEvent:any) {
              var reader = new FileReader();
              reader.onload = function (loadEvent) {
                  $scope.$apply(function () {
                      $scope.ngFileModel = {
                          lastModified: changeEvent.target.files[0].lastModified,
                          lastModifiedDate: changeEvent.target.files[0].lastModifiedDate,
                          name: changeEvent.target.files[0].name,
                          size: changeEvent.target.files[0].size,
                          type: changeEvent.target.files[0].type,
                          data: changeEvent.target.files[0]
                      };
                  });
              }
              reader.readAsDataURL(changeEvent.target.files[0]);
          });
      }
  }
}])

y use FormDatapara cargar archivos en su función.

var formData = new FormData();
 formData.append("document", $scope.ngFileModel.data)
 formData.append("user_id", $scope.userId)

todos los créditos van para https://github.com/mistralworks/ng-file-model

Me he enfrentado a un pequeño problema, puedes consultarlo aquí: https://github.com/mistralworks/ng-file-model/issues/7

Finalmente, aquí hay un repositorio bifurcado: https://github.com/okasha93/ng-file-model/blob/patch-1/ng-file-model.js

Abdallah Okasha
fuente
0

El código ayudará a insertar el archivo

<body ng-app = "myApp">
<form ng-controller="insert_Ctrl"  method="post" action=""  name="myForm" enctype="multipart/form-data" novalidate>
    <div>
        <p><input type="file" ng-model="myFile" class="form-control"  onchange="angular.element(this).scope().uploadedFile(this)">
            <span style="color:red" ng-show="(myForm.myFile.$error.required&&myForm.myFile.$touched)">Select Picture</span>
        </p>
    </div>
    <div>
        <input type="button" name="submit"  ng-click="uploadFile()" class="btn-primary" ng-disabled="myForm.myFile.$invalid" value="insert">
    </div>
</form>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> 
<script src="insert.js"></script>
</body>

insert.js

var app = angular.module('myApp',[]);
app.service('uploadFile', ['$http','$window', function ($http,$window) {
    this.uploadFiletoServer = function(file,uploadUrl){
        var fd = new FormData();
        fd.append('file', file);
        $http.post(uploadUrl, fd, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        })
        .success(function(data){
            alert("insert successfull");
            $window.location.href = ' ';//your window location
        })
        .error(function(){
            alert("Error");
        });
    }
}]);
app.controller('insert_Ctrl',  ['$scope', 'uploadFile', function($scope, uploadFile){
    $scope.uploadFile = function() {
        $scope.myFile = $scope.files[0];
        var file = $scope.myFile;
        var url = "save_data.php";
        uploadFile.uploadFiletoServer(file,url);
    };
    $scope.uploadedFile = function(element) {
        var reader = new FileReader();
        reader.onload = function(event) {
            $scope.$apply(function($scope) {
                $scope.files = element.files;
                $scope.src = event.target.result  
            });
        }
        reader.readAsDataURL(element.files[0]);
    }
}]);

save_data.php

<?php
    require "dbconnection.php";
    $ext = pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION);
    $image = time().'.'.$ext;
    move_uploaded_file($_FILES["file"]["tmp_name"],"upload/".$image);
    $query="insert into test_table values ('null','$image')";
    mysqli_query($con,$query);
?>
Hajis Hakkim
fuente
0

esto funciona

file.html

<html>
   <head>
      <script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
   </head>
   <body ng-app = "app">
      <div ng-controller = "myCtrl">
         <input type = "file" file-model = "myFile"/>
         <button ng-click = "uploadFile()">upload me</button>
      </div>
   </body>
   <script src="controller.js"></script>
</html>

controller.js

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

     app.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(res){
                console.log(res);
           }).error(function(error){
                console.log(error);
           });
        }
     }]);

     app.controller('fileCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
        $scope.uploadFile = function(){
           var file = $scope.myFile;

           console.log('file is ' );
           console.dir(file);

           var uploadUrl = "/fileUpload.php";  // upload url stands for api endpoint to handle upload to directory
           fileUpload.uploadFileToUrl(file, uploadUrl);
        };
     }]);

  </script>

fileupload.php

  <?php
    $ext = pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION);
    $image = time().'.'.$ext;
    move_uploaded_file($_FILES["file"]["tmp_name"],__DIR__. ' \\'.$image);
  ?>
Adeojo Emmanuel IMM
fuente
0

SUBIR ARCHIVOS

<input type="file" name="resume" onchange="angular.element(this).scope().uploadResume()" ng-model="fileupload" id="resume" />


        $scope.uploadResume = function () { 
            var f = document.getElementById('resume').files[0];
            $scope.selectedResumeName = f.name;
            $scope.selectedResumeType = f.type;
            r = new FileReader();

            r.onloadend = function (e) { 
                $scope.data = e.target.result;
            }

            r.readAsDataURL(f);

        };

DESCARGAR ARCHIVOS:

          <a href="{{applicant.resume}}" download> download resume</a>

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

            app.config(['$compileProvider', function ($compileProvider) {
                $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|local|data|chrome-extension):/);
                $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|local|data|chrome-extension):/);

            }]);
corriente continua
fuente
-1
app.directive('ngUpload', function () {   
  return {    
    restrict: 'A',  
    link: function (scope, element, attrs) {

      var options = {};
      options.enableControls = attrs['uploadOptionsEnableControls'];

      // get scope function to execute on successful form upload
      if (attrs['ngUpload']) {

        element.attr("target", "upload_iframe");
        element.attr("method", "post");

        // Append a timestamp field to the url to prevent browser caching results
        element.attr("action", element.attr("action") + "?_t=" + new Date().getTime());

        element.attr("enctype", "multipart/form-data");
        element.attr("encoding", "multipart/form-data");

        // Retrieve the callback function
        var fn = attrs['ngUpload'].split('(')[0];
        var callbackFn = scope.$eval(fn);
        if (callbackFn == null || callbackFn == undefined || !angular.isFunction(callbackFn))
        {
          var message = "The expression on the ngUpload directive does not point to a valid function.";
          // console.error(message);
          throw message + "\n";
        }                      

        // Helper function to create new  i frame for each form submission
        var addNewDisposableIframe = function (submitControl) {
          // create a new iframe
          var iframe = $("<iframe id='upload_iframe' name='upload_iframe' border='0' width='0' height='0' style='width: 0px; height: 0px;
border: none; display: none' />");

          // attach function to load event of the iframe
          iframe.bind('load', function () {

              // get content - requires jQuery
              var content = iframe.contents().find('body').text();

              // execute the upload response function in the active scope
              scope.$apply(function () { callbackFn(content, content !== "" /* upload completed */); });

              // remove iframe
              if (content != "") // Fixes a bug in Google Chrome that dispose the iframe before content is ready.
                setTimeout(function () { iframe.remove(); }, 250);


              submitControl.attr('disabled', null);
              submitControl.attr('title', 'Click to start upload.');
            });

          // add the new iframe to application
          element.parent().append(iframe);
        };

        // 1) get the upload submit control(s) on the form (submitters must be decorated with the 'ng-upload-submit' class)
        // 2) attach a handler to the controls' click event
        $('.upload-submit', element).click(
          function () {

            addNewDisposableIframe($(this) /* pass the submit control */);

            scope.$apply(function () { callbackFn("Please wait...", false /* upload not completed */); });



            var enabled = true;
            if (options.enableControls === null || options.enableControls === undefined || options.enableControls.length >= 0) {
              // disable the submit control on click
              $(this).attr('disabled', 'disabled');
              enabled = false;
            }

            $(this).attr('title', (enabled ? '[ENABLED]: ' : '[DISABLED]: ') + 'Uploading, please wait...');

            // submit the form
            $(element).submit();
          }
        ).attr('title', 'Click to start upload.');
      }
      else
        alert("No callback function found on the ngUpload directive.");     
    }   
  }; 
});



<form class="form form-inline" name="uploadForm" id="uploadForm"
ng-upload="uploadForm12"  action="rest/uploadHelpFile"  method="post"
enctype="multipart/form-data" style="margin-top: 3px;margin-left:
6px"> <button type="submit" id="mbUploadBtn" class="upload-submit"
ng-hide="true"></button> </form>

@RequestMapping(value = "/uploadHelpFile", method =
RequestMethod.POST)   public @ResponseBody String
uploadHelpFile(@RequestParam(value = "file") CommonsMultipartFile[]
file,@RequestParam(value = "fileName") String
fileName,@RequestParam(value = "helpFileType") String
helpFileType,@RequestParam(value = "helpFileName") String
helpFileName) { }
Rajasekhar T
fuente
formatee su respuesta no está en formato correcto
Saineshwar