Datei-Upload mit AngularJS

296

Hier ist mein HTML-Formular:

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

Ich möchte ein Bild vom lokalen Computer hochladen und den Inhalt der hochgeladenen Datei lesen. All dies möchte ich mit AngularJS tun.

Wenn ich versuche, den Wert zu drucken, wird $scope.fileer als undefiniert eingestuft.

Aditya Sethi
quelle

Antworten:

344

Einige der Antworten hier schlagen die Verwendung vor FormData(), aber leider ist dies ein Browserobjekt, das in Internet Explorer 9 und darunter nicht verfügbar ist. Wenn Sie diese älteren Browser unterstützen müssen, benötigen Sie eine Sicherungsstrategie wie die Verwendung von <iframe>oder Flash.

Es gibt bereits viele Angular.js-Module zum Hochladen von Dateien. Diese beiden unterstützen explizit ältere Browser:

Und einige andere Optionen:

Eine davon sollte zu Ihrem Projekt passen oder Ihnen einen Einblick geben, wie Sie es selbst codieren können.

Anoyz
quelle
4
Eine weitere Lösung (IaaS zum Hochladen von Dateien): github.com/uploadcare/angular-uploadcare
David Avsajanishvili
27
EggHead hat ein gutes Video zu diesem Thema --gghead.io/lessons/angularjs-file-uploads
Adam Zerner
2
danialfarid / angle-file-upload wird in ng-file-upload umbenannt
Michael
5
3 Jahre alte Antwort. IE 9 ist jetzt im Jahr 2016
tot
5
Ich denke, Sie sollten Ihre Antwort aktualisieren, um eine richtige Lösung zu finden, anstatt auf Links zu verweisen. Das ist der Weg des Stapelüberlaufs. Ansonsten machen Sie das einfach als Kommentar.
Alex Reynolds
178

Am einfachsten ist es nämlich, die HTML5-API zu verwenden FileReader

HTML ist ziemlich einfach:

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

Definieren Sie in Ihrem Controller die Methode 'add':

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

Browser-Kompatibilität

Desktop-Browser

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

Mobile Browser

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

Hinweis: Die Methode readAsBinaryString () ist veraltet und stattdessen sollte readAsArrayBuffer () verwendet werden.

Yagger
quelle
10
FileReader ist eine Klasse aus der Standard-HTML5-Datei-API w3.org/TR/FileAPI . Sie können Daten aus einer im HTML-Eingabeelement angegebenen Datei lesen und innerhalb der onloadendRückruffunktion verarbeiten. Sie benötigen keine Bibliothek, um diese API zu verwenden. Sie befindet sich bereits in Ihrem Browser (es sei denn, Sie verwenden eine sehr alte). Hoffe das hilft.
Yagger
15
FileReader.readAsBinaryString ist ab dem 12. Juli 2012 Working Draft des W3C veraltet.
Shane Stillwell
13
Sie sollten nicht mit Winkel auf DOM zugreifen. Ist eine sehr schlechte Praxis.
Jeanmatthieud
9
@Siderex, nicht in der Steuerung, aber es ist total toll, es aus der Direktive zu tun. Genau dafür sind Richtlinien gedacht. Sie können darüber in Angular docs docs.angularjs.org/guide/directive
yagger
1
@yagger Gibt es einen bestimmten Grund, warum Ihre Links auf die FileReaderSync- readAsArrayBufferMethode (die nur in Web- Workern verfügbar ist) anstatt auf die reguläre asynchrone FileReader-API verweisen ?
Doldt
58

Dies ist der moderne Browser-Weg ohne Bibliotheken von Drittanbietern. Funktioniert mit allen aktuellen Browsern.

 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 (nur Front-End) https://jsfiddle.net/vince123/8d18tsey/31/

Vince Verhoeven
quelle
Wie würden Sie die Datei im Knoten abrufen?
Juicy
Noch mehr Details? Benötigen Sie eine ng-submitoder eine Formularaktion? Dies allein macht nichts
Aron
@ Emaborsa Hallo, ich habe eine jsfiddle hinzugefügt und ein vollständigeres PHP-Codebeispiel erstellt. Das Bild wird gesendet, nachdem sich der Wert der Dateieingabe geändert hat, sodass kein ng-submit erforderlich ist.
Vince Verhoeven
Die einfachste Lösung, aber ich habe ewig gebraucht, um herauszufinden, wie ich meine WCF-Dienste dazu bringen kann, mit den hochgeladenen Daten umzugehen. Es ist wichtig, dass Sie den Datenstrom nehmen und ihn durch etwas wie MultiParser leiten , um die Daten der Datei tatsächlich einzulesen: stackoverflow.com/a/23702692/391605 Andernfalls speichern Sie Rohbytes von "------ WebKitFormBoundary" Inhaltliche Disposition: ... etc .. "
Mike Gledhill
Ich musste dem $ http-Anforderungsobjekt die Eigenschaft 'transformRequest: angle.identity' hinzufügen, wie von Manoy Ojha ein wenig weiter unten gezeigt, da sonst der Inhaltstyp nicht richtig festgelegt würde und das Beispiel nicht funktionieren würde.
Gregor Slavec
38

Unten sehen Sie ein Arbeitsbeispiel für das Hochladen von Dateien:

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

In dieser einen Funktion wird aufgerufen

setFiles

Aus der Ansicht, die das Dateiarray im Controller aktualisiert

oder

Sie können das Hochladen von jQuery-Dateien mit AngularJS überprüfen

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

JQuery Guru
quelle
Hallo, ich habe nach etwas gesucht, über das ich einfach eine Datei hochladen und direkt darunter anzeigen kann. In Ihrem Beispiel konnte ich dies jedoch nicht tun. Es macht mir nichts aus, aber ich bin neu in diesem Winkel und meine Absicht zu lernen, dieses spezielle Ziel auf einfachere und dennoch robuste Weise zu erreichen.
Aditya Sethi
Das hat sehr geholfen. Vielen Dank!
RachelD
Hervorragendes Beispiel ohne zusätzliche Bibliothek / Erweiterung. Vielen Dank.
Markdsievers
4
Sehr hilfreich, nur ein Hinweis. Dies verwendet die Datei-API, die in IE9 oder niedriger nicht funktioniert.
ArjaaAine
Irgendeine Idee, wie ich Fehler vom Ergebnis bekomme? Server könnte einen Fehler auslösen und ich möchte diese Fehlermeldung anzeigen ...
CularBytes
17

Mit flow.js können Sie einen schönen Upload von Dateien und Ordnern erzielen .

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

Schauen Sie sich hier eine Demo an

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

IE7, IE8, IE9 werden nicht unterstützt, sodass Sie möglicherweise eine Kompatibilitätsebene verwenden müssen

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

Fizer Khan
quelle
`flow.js 'ist fantastisch, aber noch nicht dokumentiert. Ich muss einen einzelnen Upload bearbeiten und eine Vorschau hinzufügen sowie die Ereignisschaltfläche getrennt senden, aber ich weiß nicht, wie ich das machen soll.
Francis Rodrigues
14

Verwenden Sie das onchangeEreignis, um das Eingabedateielement an Ihre Funktion zu übergeben.

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

Wenn ein Benutzer eine Datei auswählt, haben Sie einen Verweis darauf, ohne dass der Benutzer auf die Schaltfläche "Hinzufügen" oder "Hochladen" klicken muss.

$scope.fileSelected = function (element) {
    var myFileSelected = element.files[0];
};
James Lawruk
quelle
2
Dies funktioniert nicht wie gewünscht. Dies ist mein Workflow: 1. Aktualisieren Sie die Seite 2. Fügen Sie eine neue Datei hinzu. ** Die erste hinzugefügte Datei ist immer undefiniert. ** 3. Fügen Sie eine weitere Datei hinzu. Von nun an ist jede hochgeladene Datei die vorherige Datei, die ich hinzugefügt habe. Für die zweite Datei, die ich hinzufüge, würde dies die erste Datei hochladen, die ich hinzugefügt habe (was tatsächlich fehlgeschlagen ist)
Pulkit Pahwa
1
die beste Methode!
Stepan Yakovenko
11

Ich habe alle Alternativen ausprobiert, die @Anoyz (Richtige Antwort) bietet ... und die beste Lösung ist https://github.com/danialfarid/angular-file-upload

Einige Eigenschaften:

  • Fortschritt
  • Multifiles
  • Felder
  • Alte Browser (IE8-9)

Es funktioniert gut für mich. Sie müssen nur auf Anweisungen achten.

Auf der Serverseite verwende ich NodeJs, Express 4 und Multer Middleware, um mehrteilige Anforderungen zu verwalten.

Javier Cornejo Alfaro
quelle
Wie zeigen Sie Bilder? Vom Backend aus werden sie erfolgreich gestartet, aber sie werden als, nlzt9LJWRrAZEO3ZteZUOgGcaber ohne das PNG-Format gespeichert. Wie füge ich das hinzu?
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>

Skripte

  <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
quelle
9

Das <input type=file>Element funktioniert standardmäßig nicht mit der ng-model-Direktive . Es braucht eine benutzerdefinierte Direktive :

Arbeitsdemo der select-ng-filesRichtlinie, die mit 1 funktioniertng-model

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

Beim Senden eines POST mit einem Dateiobjekt ist es wichtig, dies festzulegen 'Content-Type': undefined. Die XHR-Sendemethode erkennt dann das Dateiobjekt und legt den Inhaltstyp automatisch fest.

georgeawg
quelle
7

Einfach mit einer Direktive

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

In der Direktive stellen wir sicher, dass ein neuer Bereich erstellt wird, und warten dann auf Änderungen, die am Dateieingabeelement vorgenommen wurden. Wenn Änderungen mit "emittieren" erkannt werden, senden Sie ein Ereignis an alle Vorgängerbereiche (nach oben) mit dem Dateiobjekt als Parameter.

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

Dann in Ihrem Ajax-Anruf:

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

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

Asher
quelle
7

Ich denke, das ist der eckige Datei-Upload:

ng-Datei-Upload

Lightweight Angular JS-Direktive zum Hochladen von Dateien.

Hier ist die DEMO- Seite

  • Unterstützt den Upload-Fortschritt, das Abbrechen / Abbrechen des Uploads während des Vorgangs, das Ziehen und Ablegen von Dateien (HTML5), das Ziehen und Ablegen von Verzeichnissen (Webkit), CORS-, PUT- (HTML5) / POST-Methoden, die Überprüfung von Dateityp und -größe sowie die Vorschau ausgewählter Bilder / Audio / Videos.
  • Browserübergreifender Datei-Upload und FileReader (HTML5 und Nicht-HTML5) mit Flash Polyfill FileAPI. Ermöglicht die clientseitige Überprüfung / Änderung vor dem Hochladen der Datei
  • Direkter Upload zu den Datenbankdiensten CouchDB, imgur usw. mit dem Inhaltstyp der Datei unter Verwendung von Upload.http (). Dies aktiviert das Fortschrittsereignis für eckige http POST / PUT-Anforderungen.
  • Separate Shim-Datei, FileAPI-Dateien werden bei Bedarf für Nicht-HTML5-Code geladen, was bedeutet, dass kein zusätzliches Laden / Code erforderlich ist, wenn Sie nur HTML5-Unterstützung benötigen.
  • Leichtgewichtig mit normalem $ http zum Hochladen (mit Shim für Nicht-HTML5-Browser), sodass alle eckigen $ http-Funktionen verfügbar sind

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

Mohamad Shiralizadeh
quelle
6

Ihre Datei und JSON-Daten werden gleichzeitig hochgeladen.

// 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ı
quelle
4

Sie können ein FormDataObjekt verwenden, das sicher und schnell ist:

// 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
quelle
Können Sie bitte auch erklären, wo 'contentChanged' genau verwendet wird?
Marc J. Schmidt
Wenn sich eine Dateieingabe ändert, wird durch Auslösen dieser Funktion der Upload-Vorgang gestartet.
Farsheed
1
Da gibt es keine <input type="file" ng-change="contentChanged($event)">, wie geht das?
Marc J. Schmidt
3

http://jsfiddle.net/vishalvasani/4hqVu/ funktioniert gut in Chrome und IE (wenn Sie CSS im Hintergrundbild ein wenig aktualisieren). Dies wird zum Aktualisieren des Fortschrittsbalkens verwendet:

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

In FireFox werden die [Prozent] -Daten von Angular jedoch nicht erfolgreich in DOM aktualisiert, obwohl Dateien erfolgreich hochgeladen wurden.

mayankcpdixit
quelle
Für FF können Sie ein loadEreignis anhören. Wenn die Länge berechenbar ist, wird ein Fortschrittsereignis ausgelöst, um den erfolgreichen Upload anzuzeigen. Dafür sorgt github.com/danialfarid/angular-file-upload bereits.
Danial
Es ist da, aber in der gegebenen Geige wird es auch überprüft und angewendet. Immer noch keine Hoffnung in FF.
Mayankcpdixit
Ich denke, wenn Sie nur uploadProgress in uploadComplete aufrufen, sollte es für FF
funktionieren
NEIN, tut es nicht, und selbst wenn ja, können Sie bitte erklären, warum? Ich habe in meinem Beitrag einen Link zur Geige angegeben. Wenn möglich, können Sie es bitte auf FF aktualisieren und den Link der Kommentarlösung hier kommentieren?
Mayankcpdixit
Welche Version von Firefox?
Danial
3

Sie können IaaS für das Hochladen von Dateien in Betracht ziehen, z. B. Uploadcare . Es gibt ein Angular-Paket dafür: https://github.com/uploadcare/angular-uploadcare

Technisch gesehen ist es als Direktive implementiert und bietet verschiedene Optionen zum Hochladen und Manipulationen für hochgeladene Bilder innerhalb des Widgets:

<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 }}"
 />

Weitere Konfigurationsoptionen zum Spielen: https://uploadcare.com/widget/configure/

David Avsajanishvili
quelle
3

Ich weiß, dass dies ein verspäteter Eintrag ist, aber ich habe eine einfache Upload-Direktive erstellt. Was Sie in kürzester Zeit zum Arbeiten bringen können!

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

ng-simple-upload mehr auf Github mit einem Beispiel mit Web-API.

Shammelburg
quelle
3

HTML

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

Fügen Sie Ihrem Controller die Methode 'profileimage ()' hinzu

    $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
quelle
2

Dies sollte ein Update / Kommentar zur Antwort von @ jquery-guru sein, aber da ich nicht genug Repräsentanten habe, wird es hier hingehen. Es behebt die Fehler, die jetzt vom Code generiert werden.

https://jsfiddle.net/vzhrqotw/

Die Änderung ist im Grunde:

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

Zu:

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

Wenn Sie möchten, können Sie sich gerne an einen geeigneteren Ort begeben.

SKR
quelle
2

Ich habe den ganzen Thread gelesen und die HTML5-API-Lösung sah am besten aus. Aber es ändert meine Binärdateien und beschädigt sie auf eine Weise, die ich nicht untersucht habe. Die Lösung, die perfekt für mich funktionierte, war:

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

Serverseite (PHP):

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

Ich kann Dateien mit AngularJS mithilfe des folgenden Codes hochladen:

Die filefür das Argument , das für die Funktion übergeben werden muss , ngUploadFileUploadist , $scope.filewie pro Ihre Frage.

Der entscheidende Punkt hier ist zu verwenden transformRequest: []. Dadurch wird verhindert, dass $ http mit dem Inhalt der Datei in Konflikt gerät.

       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
quelle
0

Die oben akzeptierte Antwort ist nicht browserkompatibel. Wenn jemand Kompatibilitätsprobleme hat, versuchen Sie dies.

Geige

Code anzeigen

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

Controller-Code

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
quelle
0

in einfachen Worten

in HTML - nur den folgenden Code hinzufügen

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

in der Steuerung - Diese Funktion wird aufgerufen, wenn Sie auf die Schaltfläche "Datei hochladen" klicken. Die Datei wird hochgeladen. Sie können es trösten.

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

Fügen Sie mehr in Controllern hinzu - unten Code in die Funktion einfügen. Diese Funktion wird aufgerufen, wenn Sie auf die Schaltfläche "Hiting the API (POST)" klicken . Es werden Dateien (die hochgeladen wurden) und Formulardaten an das Backend gesendet.

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 diesem Fall habe ich den folgenden Code als Formulardaten hinzugefügt

var data ={
          msg : message,
          sub : sub,
          sendMail: sendMail,
          selectUsersAcknowledge:false
         };
Shashwat Gupta
quelle
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>

Im WinkelJS-Controller

$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
quelle
0

Wir haben HTML, CSS und AngularJS verwendet. Das folgende Beispiel zeigt, wie Sie die Datei mit AngularJS hochladen.

<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
quelle
Dies kommt von TutorialsPoint , aber zumindest haben Sie das Beispiel gut korrigiert, das aufgrund offensichtlicher Fehler nicht einmal ausgeführt werden kann!
Benito
0

Arbeitsbeispiel mit Simple Directive ( 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]);
          });
      }
  }
}])

und verwenden Sie FormData, um eine Datei in Ihrer Funktion hochzuladen.

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

Alle Credits gehen an https://github.com/mistralworks/ng-file-model

Ich habe ein kleines Problem, das Sie hier überprüfen können: https://github.com/mistralworks/ng-file-model/issues/7

Zum Schluss noch ein gegabeltes Repo: https://github.com/okasha93/ng-file-model/blob/patch-1/ng-file-model.js

Abdallah Okasha
quelle
0

Der Code hilft beim Einfügen einer Datei

<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
quelle
0

das funktioniert

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
quelle
0

DATEN HOCHLADEN

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

        };

DATEIEN HERUNTERLADEN:

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

            }]);
DC
quelle
-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.
quelle
Bitte formatieren Sie Ihre Antwort, es ist nicht im richtigen Format
Saineshwar