Как загрузить файл на s3 через nodejs express из Angularjs

0

Я столкнулся с проблемой загрузки файла на s3 с помощью nodejs express и angularjs.

Я использую угловую директиву для отправки файла на узел express и от узла до s3.

Угловая директива:

 (function() {
  'use strict';
  angular.module('app').directive('ngFileModel', ['$parse', function ($parse) {
      return {
          restrict: 'A',
          link: function (scope, element, attrs) {
              var model = $parse(attrs.ngFileModel);
              var isMultiple = attrs.multiple;
              var modelSetter = model.assign;
              element.bind('change', function () {
                  var values = [];
                  angular.forEach(element[0].files, function (item) {
                      var value = {
                         // File Name 
                          name: item.name,
                          //File Size 
                          size: item.size,
                          //File URL to view 
                          url: URL.createObjectURL(item),
                          // File Input Value 
                          _file: item
                      };
                      values.push(value);
                  });
                  scope.$apply(function () {
                      if (isMultiple) {
                          modelSetter(scope, values);
                      } else {
                          modelSetter(scope, values[0]);
                      }
                  });
              });
          }
      };
  }]);


})();

Html-код

<input type="file" id="upme" ng-file-model="files" multiple style="display:none;" />
         <div ng-if="files.length>0" ng-init="vm.uploadFile()"></div>

Серверная сторона:

exports.upload = function(req, res){
  var images = req.body.images;

    //res.send(images);
   // console.dir(images)

   images.forEach(function(file){


   // console.dir(file);
    S3.upFile('testbucket',file.name, file.url, function(err, data){

      if(err){
        console.log(err)
      }else{
        console.dir(data);
      }

    });

   });

Проблема. Функция загрузки работает, и я получаю, что что-то было загружено в ведро s3, имя файла отображается в ведре; но кажется, что это не фактический размер файла, и я не могу открыть его. когда я нажимаю на файл url, он говорит, чтобы загрузить файл, после загрузки файла он не открывается. Я думаю, что может возникнуть проблема с синтаксическим анализом файла на узле сервера до загрузки в s3. Но я не могу определить, какое решение должно быть там.

Я также получаю одну ошибку в консоли.

TypeError: path must be a string or Buffer
    at TypeError (native)
    at Object.fs.open (fs.js:625:11)
    at ReadStream.open (fs.js:1708:6)
    at new ReadStream (fs.js:1695:10)
    at Object.fs.createReadStream (fs.js:1643:10)

Я сделал функцию загрузки файла s3 как модуль в отдельный файл. Вот функция модуля загрузки файлов

// uploading file or object into bucket
exports.upFile = function(bucket_name, key, file, next){

  var params = {Bucket: bucket_name, Key: key, Body: fs.createReadStream(file), ACL:"public-read"};
  s3.upload(params, function(err, data) {
    next(err, data);
  });

};

Я ценю любую помощь экспертов.

Теги:
amazon-s3
express

1 ответ

1
Лучший ответ

Вы не указываете файл как аргумент функции загрузки, а URL-адрес объекта. Чтобы исправить вашу реализацию, вы должны внести некоторые изменения в угловое. Во-первых, вы должны отправлять файлы в виде данных многострочной формы из угловых. Вы можете добиться этого, используя:

var form = new formData();
angular.forEach(element[0].files, function (item) {
    form.append('file', item);
});

Отправьте данные этой формы на ваш сервер узла с помощью HTTP-запроса. Вы можете определить маршрут и метод http, используя выражение в nodejs. В угловом порядке запрос должен выглядеть примерно так:

$http.post('/test_route', form, {
   withCredentials: false,
   headers: {
       'Content-Type': undefined
   },
   trnasformRequest: angular.identity
}).success(function(data) {
    // do something with data from server
});

На сервере узла, когда вы получаете запрос, вам необходимо извлечь файлы из данных формы. Сначала определите маршрут и метод, используя выражение:

var multiparty = require('multiparty');

app.post('test_route', function(req, res) {
    var form = new multiparty.Form();
    form.parse(req, function(err, fields, files) {
        var files_to_uplaod = files.file;
        files_to_upload.forEach(function(file) {
            read_file = fs.readFileSync(file.path);
            var params = {Bucket: bucket_name, Key: file.originalFilename, Body: read_file, ACL:"public-read"};
            s3.upload(params, function(err, data) {
                next(err, data);
                // once the file is uploaded you can remove the file from local disk which is saved whn multipart data arrives.
                fs.unlink(file.path, function(err) {
                    if (err) {console.log(err);}
                });   
            });
        });
    }
});

Для анализа многоуровневого сервера узлов используйте многопартийный модуль. Более подробную информацию можно найти здесь: https://www.npmjs.com/package/multiparty

Ещё вопросы

Сообщество Overcoder
Наверх
Меню