Przesyłanie plików za pomocą AngularJS

296

Oto moja forma HTML:

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

Chcę załadować obraz z komputera lokalnego i chcę przeczytać zawartość przesłanego pliku. Wszystko to chcę zrobić za pomocą AngularJS.

Kiedy próbuję wydrukować, jego wartość $scope.filejest nieokreślona.

Aditya Sethi
źródło

Odpowiedzi:

344

Niektóre odpowiedzi tutaj proponują użycie FormData(), ale niestety jest to obiekt przeglądarki niedostępny w Internet Explorerze 9 i niższych. Jeśli potrzebujesz obsługi tych starszych przeglądarek, potrzebujesz strategii tworzenia kopii zapasowych, takiej jak przy użyciu <iframe>lub Flash.

Istnieje już wiele modułów Angular.js do przesyłania plików. Te dwa mają wyraźne wsparcie dla starszych przeglądarek:

I kilka innych opcji:

Jeden z nich powinien pasować do twojego projektu lub może dać ci wgląd w to, jak samemu go zakodować.

Anoyz
źródło
4
Jeszcze jedno rozwiązanie (IaaS do przesyłania plików): github.com/uploadcare/angular-uploadcare
David Avsajanishvili,
27
EggHead ma dobre wideo na ten temat - egghead.io/lessons/angularjs-file-uploads
Adam Zerner
2
danialfarid / angular-file-upload zostaje przemianowany na ng-file-upload
Michael
5
3-letnia odpowiedź. IE 9 jest teraz
martwy
5
Myślę, że powinieneś zaktualizować swoją odpowiedź, aby mieć właściwe rozwiązanie zamiast wskazywać linki. To sposób przepełnienia stosu. W przeciwnym razie po prostu zrób to jako komentarz.
Alex Reynolds,
178

Najłatwiej jest użyć interfejsu API HTML5, a mianowicie FileReader

HTML jest dość prosty:

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

W kontrolerze zdefiniuj metodę „dodaj”:

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

Kompatybilność z przeglądarkami

Przeglądarki stacjonarne

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

Przeglądarki mobilne

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

Uwaga: metoda readAsBinaryString () jest przestarzała i zamiast niej należy użyć metody readAsArrayBuffer () .

kudły
źródło
10
FileReader to klasa ze standardowego interfejsu API plików HTML5 w3.org/TR/FileAPI . Pozwala odczytać dane z pliku określonego w elemencie wejściowym HTML i przetworzyć je w onloadendfunkcji wywołania zwrotnego. Nie potrzebujesz żadnej biblioteki, aby korzystać z tego API, jest już w przeglądarce (chyba że używasz bardzo starej). Mam nadzieję że to pomoże.
yagger
15
FileReader.readAsBinaryString jest przestarzałe od 12 lipca 2012 Robocza wersja robocza z W3C.
Shane Stillwell
13
Nie powinieneś uzyskiwać dostępu do DOM za pomocą kątownika. To bardzo zła praktyka.
jeanmatthieud
9
@Siderex, nie w kontrolerze, ale wspaniale jest to zrobić z dyrektywy. Właśnie do tego służą dyrektywy. Możesz o tym przeczytać w Angular docs docs.quarejs.org/guide/directive
yagger
1
@yagger czy istnieje szczególny powód, dla którego twoje linki odwołują się do readAsArrayBuffermetody FileReaderSync (która jest dostępna tylko w robotach sieciowych) zamiast zwykłego, asynchronicznego interfejsu API FileReader ?
doldt
58

Jest to nowoczesny sposób przeglądarki, bez bibliotek stron trzecich. Działa na wszystkich najnowszych przeglądarkach.

 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 (tylko front-end) https://jsfiddle.net/vince123/8d18tsey/31/

Vince Verhoeven
źródło
Jak pobrać plik w węźle?
Juicy
Jakieś szczegóły? Potrzebujesz akcji ng-submitlub formularza? To samo z siebie nic nie robi
Aron
@Emaborsa hello Dodałem jsfiddle i stworzyłem pełniejszy przykład kodu php. Przesyła obraz po zmianie wartości wejściowej pliku, więc nie jest wymagane przesyłanie ng.
Vince Verhoeven
Idealne najprostsze rozwiązanie, ale zajęło mi wieki, aby dowiedzieć się, jak zmusić moje usługi WCF do radzenia sobie z przesyłanymi danymi. Jest to istotne , aby podjąć strumienia danych i przekazać go przez coś podobnego MultiParser właściwie odczytywać dane pliku: stackoverflow.com/a/23702692/391605 Inaczej będziesz przechowywania surowych bajtów „------ WebKitFormBoundary Treść-usposobienie: ... itd. ”
Mike Gledhill
Musiałem dodać właściwość „transformRequest: angular.identity” do obiektu żądania $ http, jak pokazał Manoy Ojha trochę dalej, w przeciwnym razie Typ treści nie byłby ustawiony poprawnie i przykład nie działałby.
Gregor Slavec
38

Poniżej znajduje się przykładowy przykład przesłania pliku:

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

W tej jednej funkcji o nazwie

setFiles

Z widoku, który zaktualizuje tablicę plików w kontrolerze

lub

Możesz sprawdzić przesyłanie plików jQuery za pomocą AngularJS

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

JQuery Guru
źródło
Cześć, szukałem czegoś, przez co mogę po prostu załadować jeden plik i wyświetlić tuż pod nim. Jednak w twoim przykładzie nie byłem w stanie zrobić tego samego. Nie przejmuj się, ale jestem nowy w tych angularjach i mam zamiar nauczyć się realizować ten konkretny cel w prostszy, ale solidny sposób.
Aditya Sethi,
To bardzo pomogło. Dzięki!
RachelD
Doskonały przykład bez użycia dodatkowej biblioteki / rozszerzenia. Dzięki.
markdsievers
4
Bardzo pomocna, tylko uwaga ... używa interfejsu API File, który nie działa w IE9 lub niższej
ArjaaAine
Masz pomysł, jak uzyskać błędy z wyniku? Serwer może wyrzucić błąd i chciałbym wyświetlić ten komunikat o błędzie ...
CularBytes
17

Można osiągnąć piękny plik i folder przesyłać za pomocą flow.js .

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

Sprawdź demo tutaj

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

Nie obsługuje IE7, IE8, IE9, więc w końcu będziesz musiał użyć warstwy kompatybilności

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

Fizer Khan
źródło
`flow.js 'jest fantastyczny, ale brakuje mu jeszcze dokumentacji. Potrzebuję zmanipulować pojedyncze przesłanie i dodać podgląd, a także osobno wysłać przycisk zdarzenia, ale nie wiem, jak to zrobić.
Francis Rodrigues,
14

Użyj onchangezdarzenia, aby przekazać element pliku wejściowego do funkcji.

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

Tak więc, gdy użytkownik wybiera plik, masz do niego odniesienie, bez konieczności klikania przycisku „Dodaj” lub „Prześlij”.

$scope.fileSelected = function (element) {
    var myFileSelected = element.files[0];
};
James Lawruk
źródło
2
To nie działa zgodnie z oczekiwaniami. Oto mój przepływ pracy: 1. Odśwież stronę 2. Dodaj nowy plik. ** Pierwszy dodany plik jest zawsze niezdefiniowany. ** 3. Dodaj kolejny plik. Od teraz każdy przesłany plik jest poprzednim plikiem, który dodałem. Tak więc dla drugiego pliku, który dodam, załadowałbym pierwszy plik, który dodałem (który faktycznie nie powiódł się)
Pulkit Pahwa
1
najlepsza metoda!
Stepan Yakovenko
11

Wypróbowałem wszystkie alternatywy, które daje @Anoyz (poprawna odpowiedź) ... a najlepszym rozwiązaniem jest https://github.com/danialfarid/angular-file-upload

Niektóre funkcje:

  • Postęp
  • Multifile
  • Pola
  • Stare przeglądarki (IE8-9)

Dla mnie działa dobrze. Musisz tylko zwrócić uwagę na instrukcje.

Po stronie serwera używam oprogramowania pośredniego NodeJs, Express 4 i Multer do zarządzania żądaniami wieloczęściowymi.

Javier Cornejo Alfaro
źródło
Jak wyświetlasz obrazy? Z backendu z powodzeniem wchodzą, ale są zapisywane jako, nlzt9LJWRrAZEO3ZteZUOgGcale bez formatu .png. Jak to dodać?
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>

Skrypty

  <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
źródło
9

<input type=file>Element nie domyślnie pracy z dyrektywą ng-modelu . Potrzebuje niestandardowej dyrektywy :

Demonstracja robocza select-ng-filesdyrektywy, która działa z 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.postz listy plików

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

Podczas wysyłania testu POST z obiektem File należy ustawić 'Content-Type': undefined. Metoda wysyłania XHR wykryje wówczas obiekt File i automatycznie ustawi typ zawartości.

georgeawg
źródło
7

Łatwe dzięki dyrektywie

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

W dyrektywie zapewniamy utworzenie nowego zakresu, a następnie nasłuchujemy zmian wprowadzonych w elemencie wejściowym pliku. Po wykryciu zmian emituj zdarzenie do wszystkich zakresów przodków (w górę) z obiektem pliku jako parametrem.

W twoim kontrolerze:

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

Następnie w wywołaniu 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
źródło
7

myślę, że jest to przesyłanie pliku kątowego:

przesyłanie pliku ng

Lekka dyrektywa Angular JS do przesyłania plików.

Oto DEMO page.Features

  • Obsługuje postęp przesyłania, anuluj / przerwij przesyłanie w trakcie, przeciągnij i upuść plik (html5), przeciągnij i upuść katalog (webkit), metody CORS, PUT (html5) / POST, sprawdzanie poprawności typu i rozmiaru pliku, wyświetl podgląd wybranych zdjęć / audio / wideo.
  • Przesyłanie plików między przeglądarkami i FileReader (HTML5 i nie HTML5) z Flash FileFI FileFill. Umożliwia walidację / modyfikację po stronie klienta przed przesłaniem pliku
  • Bezpośrednie przesyłanie do usług db CouchDB, imgur itp. Z typem zawartości pliku za pomocą Upload.http (). Umożliwia to zdarzenie postępu dla kątowych żądań HTTP POST / PUT.
  • Oddzielny plik podkładki, pliki FileAPI są ładowane na żądanie dla kodu innego niż HTML5, co oznacza brak dodatkowego ładowania / kodu, jeśli potrzebujesz tylko obsługi HTML5.
  • Lekki przy użyciu zwykłego $ http do przesyłania (z podkładką dla przeglądarek nieobsługujących HTML5), dzięki czemu wszystkie funkcje $ http kątowe są dostępne

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

Mohamad Shiralizadeh
źródło
6

Przesyłanie pliku i danych json w tym samym czasie.

// 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ı
źródło
4

Możesz użyć FormDataobiektu, który jest bezpieczny i szybki:

// 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);
    });
}
Przeklęty
źródło
Czy możesz również wyjaśnić, gdzie dokładnie używa się „contentChanged”?
Marc J. Schmidt,
Gdy dane wejściowe pliku ulegną zmianie, uruchomienie tej funkcji rozpocznie proces przesyłania.
Farsheed,
1
Skoro nie ma <input type="file" ng-change="contentChanged($event)">, jak to zrobić?
Marc J. Schmidt,
3

http://jsfiddle.net/vishalvasani/4hqVu/ działa dobrze w Chrome i IE (jeśli zaktualizujesz CSS trochę w obrazie tła). Służy to do aktualizacji paska postępu:

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

ale w FireFox dane [procentowe] programu angular nie zostały pomyślnie zaktualizowane w DOM, chociaż pliki są ładowane pomyślnie.

mayankcpdixit
źródło
W przypadku FF można odsłuchać loadzdarzenie, a jeśli długość można obliczyć, uruchom zdarzenie postępu, aby wskazać pomyślne przesłanie. Github.com/danialfarid/angular-file-upload już się tym zajmuje.
Danial
Jest tam, ale w danym skrzypcach jest również sprawdzane i stosowane. Nadal nie ma nadziei w FF.
mayankcpdixit
Myślę, że jeśli po prostu zadzwonisz do uploadProgress w uploadComplete, to powinno działać dla FF
Danial
NIE, nie ma, a nawet jeśli tak, czy możesz wyjaśnić, dlaczego? W swoim poście podaję link do skrzypiec. Jeśli to możliwe, możesz zaktualizować go do działania w FF i skomentować link do rozwiązania tutaj?
mayankcpdixit
Jaka wersja przeglądarki Firefox?
Danial
3

Możesz rozważyć IaaS do przesyłania plików, na przykład Uploadcare . Jest do tego pakiet Angular: https://github.com/uploadcare/angular-uploadcare

Technicznie jest on implementowany jako dyrektywa, zapewniając różne opcje przesyłania i manipulowania przesłanymi obrazami w widżecie:

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

Więcej opcji konfiguracji do zabawy: https://uploadcare.com/widget/configure/

David Avsajanishvili
źródło
3

Wiem, że to późny wpis, ale stworzyłem prostą dyrektywę przesyłania. Które możesz zacząć pracować w mgnieniu oka!

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

ng-simple-upload więcej na Github na przykładzie z interfejsem API sieci Web.

Shammelburg
źródło
3

HTML

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

dodaj metodę „profileimage ()” do kontrolera

    $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
źródło
2

To powinna być aktualizacja / komentarz do odpowiedzi @ jquery-guru, ale ponieważ nie mam wystarczającej liczby powtórzeń, trafi tutaj. Naprawia błędy, które są teraz generowane przez kod.

https://jsfiddle.net/vzhrqotw/

Zmiana polega zasadniczo na:

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

Do:

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

W razie potrzeby możesz przenieść się w bardziej odpowiednie miejsce.

SKR
źródło
2

Przeczytałem cały wątek, a interfejs API HTML5 wyglądał najlepiej. Ale zmienia moje pliki binarne, niszcząc je w sposób, którego nie zbadałem. Idealnym rozwiązaniem dla mnie było:

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

Po stronie serwera (PHP):

$file_content = $_POST['file'];
$file_content = substr($file_content,
    strlen('data:text/plain;base64,'));
$file_content = base64_decode($file_content);
Camille Sauvage
źródło
1

Jestem w stanie przesyłać pliki za pomocą AngularJS, używając poniższego kodu:

The fileDo argumentu, że musi zostać przekazany do funkcji ngUploadFileUploadjest $scope.filejak na swoje pytanie.

Kluczową kwestią jest tutaj użycie transformRequest: []. Zapobiegnie to $ http z bałaganem z zawartością pliku.

       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
źródło
0

Powyższa odpowiedź nie jest kompatybilna z przeglądarką. Jeśli ktoś ma problem ze zgodnością, spróbuj tego.

Skrzypce

Wyświetl kod

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

Kod kontrolera

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
źródło
0

w prostych słowach

w HTML - dodaj tylko poniższy kod

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

w kontrolerze - Ta funkcja jest wywoływana po kliknięciu przycisku „Prześlij plik” . prześle plik. możesz to pocieszyć.

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

dodaj więcej w kontrolerach - poniżej kodu dodaj do funkcji. Ta funkcja jest wywoływana po kliknięciu przycisku „Uderzenie w API (POST)” . wyśle ​​plik (który przesłał) i dane formularza do backendu.

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

w tym przypadku .. dodałem poniższy kod jako dane formularza

var data ={
          msg : message,
          sub : sub,
          sendMail: sendMail,
          selectUsersAcknowledge:false
         };
Shashwat Gupta
źródło
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>

W sterowniku 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
źródło
0

Użyliśmy HTML, CSS i AngularJS. Poniższy przykład pokazuje, jak przesłać plik za pomocą 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
źródło
Pochodzi z TutorialsPoint , ale przynajmniej wykonałeś dobrą robotę, poprawiając ich przykład, który nie może działać nawet z powodu oczywistych błędów!
Benito,
0

Przykład roboczy z użyciem prostej dyrektywy ( model pliku 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]);
          });
      }
  }
}])

i użyj, FormDataaby przesłać plik w swojej funkcji.

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

wszystkie kredyty dotyczą https://github.com/mistralworks/ng-file-model

Napotkałem mały problem, który możesz sprawdzić tutaj: https://github.com/mistralworks/ng-file-model/issues/7

Wreszcie, oto rozwidlone repozytorium: https://github.com/okasha93/ng-file-model/blob/patch-1/ng-file-model.js

Abdallah Okasha
źródło
0

Kod pomoże wstawić plik

<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
źródło
0

to działa

plik.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
źródło
0

PRZEŚLIJ PLIKI

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

        };

POBIERZ PLIKI:

          <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
źródło
-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.
źródło
proszę sformatować odpowiedź, która nie jest w odpowiednim formacie
Saineshwar,