Загрузка файлов с помощью AngularJS

Вот моя HTML-форма:

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

Я хочу загрузить изображение с локальной машины и прочитать содержимое загруженного файла. Все это я хочу сделать с помощью AngularJS.

Когда я пытаюсь вывести значение $scope.file, оно выдается как undefined.

Комментарии к вопросу (2)
Решение

В некоторых ответах здесь предлагается использовать FormData(), но, к сожалению, это объект браузера, недоступный в Internet Explorer 9 и ниже. Если вам нужно поддерживать эти старые браузеры, вам понадобится запасная стратегия, например, использование <iframe> или Flash.

Уже существует множество модулей Angular.js для выполнения загрузки файлов. Эти два имеют явную поддержку старых браузеров:

И некоторые другие варианты:

Один из них должен подойти для вашего проекта или может дать вам некоторое представление о том, как написать код самостоятельно.

Комментарии (8)

Самое простое-это использовать HTML5 API, а именно [FileReader][1]

HTML-код очень простой:

<input type="file" id="file" name="file"/>
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);
}

Совместимости

Настольных Браузеров

в Firefox(движок Gecko) 3.6(1.9.2), хром 7, Интернет Обозреватель 10, Опера 12.02, сафари 6.0.2

Мобильные Браузеры

в Firefox(движок Gecko) 32, хром 3, интернет-обозреватель 10, Опера 11.5, в браузере Safari 6.1

Примечание : readAsBinaryString() метод является устаревшим и readAsArrayBuffer() должен использоваться вместо этого.

Комментарии (17)

Это современный способ браузера, без 3-й партии библиотек. Работает на всех последних браузерах.

 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 скрипку (только фронтальный) https://jsfiddle.net/vince123/8d18tsey/31/

Комментарии (8)

Ниже приведен рабочий пример загрузки файла:

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

В этом примере одна функция называется

setFiles

From View, которая будет обновлять массив файлов в контроллере

или

Вы можете проверить jQuery File Upload с помощью AngularJS

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

Комментарии (7)

Вы можете достичь хороший файл и загрузить папку через flow.js.

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

Проверьте здесь демо

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

Это не'т поддерживать ИЕ7, ИЕ8, ИЕ9, так что вы'll в конечном итоге придется использовать слой совместимости

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

Комментарии (1)

Используйте onChange, после событие, чтобы передать входного файла элемент вашей функции.

в <тип входного=то"файл" onChange, после="и угловые.элемент(это).области().fileSelected(это) и" />

Поэтому, когда пользователь выбирает файл, у вас есть ссылка на это, не требуя от пользователя нажмите и"Добавить" или "кнопку Загрузить и".

$scope.fileSelected = function (element) {
    var myFileSelected = element.files[0];
};
Комментарии (2)

Я попробовал все варианты, что @Anoyz (правильный ответ) дает... и самое лучшее разрешение https://github.com/danialfarid/angular-file-upload

Некоторые Особенности:

  • Прогресс
  • Multifiles
  • Поля
  • Старых браузерах (IE8-9)

Это'ы работают отлично для меня. Вы просто должны обратить внимание на инструкции.

На стороне сервера я использую NodeJs, Express 4 и Мултэр промежуточного управлять сложного запроса.

Комментарии (1)

На в <тип входного=Файл> элемент не работает по умолчанию с НГ-модель директивы. Она нужна директивы:

Рабочая демо-возвращение-файлов директивой, которая работает с НГ-модель в<SUP-серфинг>1</суп>

в

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>

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

в


`$протоколу HTTP.сообщение от список файлов

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

При отправке поста с [объектом] файлФайл важно комплект &#39;контент-тип&#39;: не определено. В XHR и отправка метод тогда будет обнаруживать [объект] файлФайл и автоматически установить тип содержимого.

Комментарии (0)

HTML-код







     <input type = "file" file-model="files" multiple/>
     upload me
     <li ng-repeat="file in files">{{file.name}}</li>

Скрипты

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

</тело> </HTML и ГТ;

Комментарии (1)

Легко с помощью директивы

HTML-код:

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

ДШ:


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
Комментарии (0)

я думаю, что это угловой загрузить файл:

НГ-файл-загрузить

Директива облегченный угловой JS для загрузки файлов.

Вот демо страницы.Особенности

  • Поддержка загрузки прогресса, отменить/отмена загрузки в прогресс, файл перетаскиванием (в HTML5), каталог перетащите и падение (на базе webkit), коров, ставить(на HTML5)/пост-способы, проверки типа файла и его размер, предварительный просмотр выбранных изображений/аудио/видео.
  • Файл кросс-браузер загрузите и FileReader (HTML5 и не на HTML5) с FileAPI Флэш-полифилл. На стороне клиента проверка/модификация: перед загрузкой файла
  • Прямая загрузка на сервис БД CouchDB, для карт, и т. д... с файл'ы типа контента, используя загрузки.протоколу HTTP(). Это позволяет событие прогресса для углового HTTP-запрос POST/PUT запросы.
  • Файл отдельно ШИМ файлов FileAPI загружаются по запросу, для некурящих код HTML5 смысл без дополнительной нагрузки/код если вам просто нужна поддержка HTML5.
  • Облегченная с использованием регулярных $HTTP для загрузки (с ШИМ для non-браузеров HTML5) так что всех угловых $http функции доступны

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

Комментарии (0)

Ваш файл и загрузки данных JSON в то же время .

в

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

в

Комментарии (0)

Вы можете использовать виде FormData объект, который является безопасным и быстрым:

// 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);
    });
}
Комментарии (3)

[http://jsfiddle.net/vishalvasani/4hqVu/](http://jsfiddle.net/vishalvasani/4hqVu/) отлично работает в chrome и IE (если немного обновить CSS в background-image). Это используется для обновления прогресс-бара:

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

но в FireFox angular's [percent] данные не обновляются в DOM успешно, хотя файлы загружаются успешно.

Комментарии (7)

Я знаю, что это поздно, но я создал простую директиву загрузки. Что вы можете получить работу в кратчайшие сроки!

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

НГ-просто-загрузки больше на GitHub с примером с помощью веб-API.

Комментарии (0)

Вы можете рассмотреть IaaS для загрузки файла, такие как Uploadcare. Есть угловой пакет для него: https://github.com/uploadcare/angular-uploadcare

Технически это'ы реализованы в качестве директивы, предоставляя различные варианты загрузки и манипуляций для загруженных изображений в виджете:

Другие варианты конфигурации, чтобы играть с: https://uploadcare.com/widget/configure/

Комментарии (0)

HTML-код

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

добавить 'profileimage()' метод в контроллер

    $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);
    }
Комментарии (0)

Это должно быть обновление/комментарий к @на jQuery-гуру'ы ответ, но как я Дон'т иметь достаточно рэп она будет идти здесь. Он исправляет ошибки, которые теперь сгенерированный код.

https://jsfiddle.net/vzhrqotw/

Изменения в основном:

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

К:

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

Не стесняйтесь, чтобы переместить в более подходящее место, если это необходимо.

Комментарии (0)

Я'вэ читать все нити и решения API в HTML5 посмотрел лучше. Но что это меняет в моей двоичные файлы, развращая их таким образом, Я'вэ не исследованы. Решение, которое прекрасно работал для меня :

HTML-код :

<input type="file" id="msds" ng-model="msds" name="msds"/>

    Upload

ДШ:

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

На стороне сервера (на PHP):

$file_content = $_POST['file'];
$file_content = substr($file_content,
    strlen('data:text/plain;base64,'));
$file_content = base64_decode($file_content);
Комментарии (0)

Я в состоянии загрузить файлы с помощью AngularJS с помощью ниже код:

"Файл" в качестве аргумента, который должен быть передан для ngUploadFileUpload функции это$охвата.файл на ваш вопрос.

Ключевым моментом здесь является использование transformRequest: []. Это позволит предотвратить $HTTP с баловаться с содержимым файла.

       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;

        }
Комментарии (0)