Caricamento file utilizzando AngularJS

Ecco il mio modulo HTML:

Voglio caricare un’immagine dalla macchina locale e voglio leggere il contenuto del file caricato. Tutto ciò che voglio fare usando AngularJS.

Quando provo a stampare il valore di $scope.file si presenta come non definito.

    Alcune delle risposte qui propongono l’utilizzo di FormData() , ma sfortunatamente si tratta di un object browser non disponibile in Internet Explorer 9 e versioni successive. Se hai bisogno di supportare quei vecchi browser, avrai bisogno di una strategia di backup come usare o Flash.

    Esistono già molti moduli Angular.js per eseguire il caricamento dei file. Questi due hanno il supporto esplicito per i browser più vecchi:

    E alcune altre opzioni:

    Uno di questi dovrebbe adattarsi al tuo progetto o potrebbe darti qualche informazione su come codificarlo da solo.

    Il modo più semplice è utilizzare l’API HTML5, ovvero FileReader

    L’HTML è piuttosto semplice:

       

    Nel controller definisci il metodo “aggiungi”:

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

    Compatibilità del browser

    Browser desktop

    Firefox (Gecko) 3.6 (1.9.2), Chrome 7, Internet Explorer * 10, Opera * 12.02, Safari 6.0.2

    Browser mobili

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

    Nota: il metodo readAsBinaryString () è deprecato e readAsArrayBuffer () dovrebbe invece essere usato.

    Questo è il modo 2015, senza le librerie di terze parti. Funziona su tutti i browser più recenti.

      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:

      

    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/

    Di seguito è riportato un esempio funzionante di caricamento dei file:

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

    In questa una funzione chiamata

     setFiles 

    Da View che aggiornerà l’array di file nel controller

    o

    Puoi controllare il caricamento di file jQuery usando AngularJS

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

    È ansible ottenere un buon caricamento di file e cartelle usando flow.js.

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

    Guarda qui una demo

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

    Non supporta IE7, IE8, IE9, quindi alla fine dovrai utilizzare un livello di compatibilità

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

    Ho provato tutte le alternative che @Anoyz (risposta corretta) dà … e la soluzione migliore è https://github.com/danialfarid/angular-file-upload

    Alcune caratteristiche:

    • Progresso
    • Multifiles
    • campi
    • Vecchi browser (IE8-9)

    Funziona bene per me. Devi solo prestare attenzione alle istruzioni.

    Sul lato server utilizzo il middleware NodeJs, Express 4 e Multer per gestire la richiesta multipart.

    HTML

        
  • {{file.name}}
  • Script

        

    Utilizzare l’evento onchange per passare l’elemento del file di input alla funzione.

    Quindi, quando un utente seleziona un file, hai un riferimento ad esso senza che l’utente debba fare clic sul pulsante “Aggiungi” o “Carica”.

     $scope.fileSelected = function (element) { var myFileSelected = element.files[0]; }; 

    Facile con una direttiva

    html:

      

    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 

    Nella direttiva assicuriamo che venga creato un nuovo ambito e quindi ascoltiamo le modifiche apportate all'elemento di input del file. Quando vengono rilevate modifiche con l'emissione di un evento su tutti gli ambiti degli antenati (verso l'alto) con l'object file come parametro.

    Nel tuo controller:

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

    Quindi nella tua chiamata ajax:

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

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

    penso che questo sia il caricamento del file angular:

    ng-di caricamento file

    Direttiva JS angular leggera per caricare i file.

    Ecco la pagina DEMO. Caratteristiche

    • Supporta l’avanzamento del caricamento, annulla / interrompe il caricamento mentre è in corso, trascina i file (html5), trascinamento della directory (webkit), CORS, PUT (html5) / metodi POST, convalida del tipo e della dimensione del file, mostra l’anteprima delle immagini selezionate / audio / video.
    • Caricamento di file cross browser e FileReader (HTML5 e non HTML5) con FileAPI Flash polyfill. Consente la convalida / modifica del lato client prima di caricare il file
    • Caricamento diretto sui servizi db CouchDB, imgur, ecc. Con il tipo di contenuto del file utilizzando Upload.http (). Ciò abilita l’evento di avanzamento per le richieste angolari HTTP POST / PUT.
    • File di shim separati, i file FileAPI vengono caricati su richiesta per un codice non HTML5 che non implica alcun carico / codice aggiuntivo se hai solo bisogno del supporto HTML5.
    • Leggero con normale $ http per caricare (con shim per browser non HTML5) in modo che siano disponibili tutte le caratteristiche angolari $ http

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

    Il caricamento di file e dati json contemporaneamente.

     // 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 // İf you can add plural file and İf 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 

    L’elemento non funziona di default con la direttiva ng-model . Ha bisogno di una direttiva personalizzata :

    Working Demo of return-files Directive che funziona con ng-model 1

     angular.module("app",[]); angular.module("app").directive("returnFiles", 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

    Files

    {{file.name}}

    È ansible utilizzare un object FormData che è sicuro e veloce:

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

    http://jsfiddle.net/vishalvasani/4hqVu/ funziona bene in chrome e IE (se aggiorni CSS un po ‘in background-image). Questo è usato per l’aggiornamento della barra di avanzamento:

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

    ma nel [percentuale] dei dati angolari di FireFox non viene aggiornato correttamente nel DOM, sebbene i file vengano caricati correttamente.

    Potresti considerare IaaS per il caricamento di file, come Uploadcare . C’è un pacchetto angular per questo: https://github.com/uploadcare/angular-uploadcare

    Tecnicamente è implementato come una direttiva, fornendo diverse opzioni per il caricamento e le manipolazioni per le immagini caricate all’interno del widget:

      

    Altre opzioni di configurazione con cui giocare: https://uploadcare.com/widget/configure/

    So che questa è una voce in ritardo, ma ho creato una semplice direttiva di upload. Che puoi lavorare in pochissimo tempo!

      

    ng-simple-upload di più su Github con un esempio usando l’API Web.

    Questo dovrebbe essere un aggiornamento / commento alla risposta di @ jquery-guru, ma poiché non ho abbastanza rep, andrà qui. Corregge gli errori che ora vengono generati dal codice.

    https://jsfiddle.net/vzhrqotw/

    Il cambiamento è fondamentalmente:

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

    A:

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

    Sentiti libero di spostarti in una posizione più appropriata se lo desideri.

    Ho letto tutto il thread e la soluzione dell’API HTML5 è risultata la migliore. Ma cambia i miei file binari, corrompendoli in un modo che non ho indagato. La soluzione che ha funzionato perfettamente per me è stata:

    HTML:

       

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

    Lato server (PHP):

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

    Nel controller 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; } 

    Sono in grado di caricare file usando AngularJS usando il seguente codice:

    Il file per l’argomento che deve essere passato per la funzione ngUploadFileUpload è $scope.file come da domanda.

    Il punto chiave qui è usare transformRequest: [] . Ciò impedirà a $ http di interferire con il contenuto del file.

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

    La risposta sopra accettata non è compatibile con browser. Se qualcuno ha problemi di compatibilità, prova questo.

    Violino

    Visualizza codice

      

    {{data}}

    Codice del controller

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

    HTML

      

    aggiungi il metodo ‘profileimage ()’ al tuo controller

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

    in parole semplici

    in Html – aggiungi solo sotto il codice

      

    nel controller – Questa funzione viene chiamata quando si fa clic su “upload file button” . caricherà il file. puoi consolarlo

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

    aggiungi altro nei controller – sotto il codice aggiungi alla funzione. Questa funzione è chiamata quando si fa clic sul pulsante che viene utilizzato “colpire l’api (POST)” . invierà il file (che ha caricato) e i dati del modulo al back-end.

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

    in questo caso ... ho aggiunto sotto il codice come dati del modulo

     var data ={ msg : message, sub : sub, sendMail: sendMail, selectUsersAcknowledge:false }; 

    Abbiamo usato HTML, CSS e AngularJS. L’esempio seguente mostra come caricare il file usando AngularJS.

          

    Esempio di lavoro usando la direttiva semplice ( modello-file-ng ):

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

    e utilizzare FormData per caricare il file nella tua funzione.

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

    tutti i crediti vanno su https://github.com/mistralworks/ng-file-model

    Ho affrontato un piccolo problema che puoi controllare qui: https://github.com/mistralworks/ng-file-model/issues/7

    Infine, ecco un repository biforcuto: https://github.com/okasha93/ng-file-model/blob/patch-1/ng-file-model.js

    Il codice aiuterà a inserire il file

      

    Select Picture

    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); ?> 

    questo funziona

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

    fileupload.php

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

    CARICARE FILES

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

    SCARICARE FILES:

       download resume 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):/); }]); 
     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 = $(""); // 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."); } }; }); 
    @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) { }