2016-07-29 60 views
0

我面临着通过nodejs express和angularjs将文件上传到s3的问题。如何通过nodejs从Angularjs上传文件到s3

我正在使用angular指令将文件发送到节点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); 
    }); 

}; 

我感谢专家的任何帮助。

回答

1

您没有将文件作为参数传递给上传函数,而是提供对象URL。要更正您的实施方案,您必须对角度进行一些更改。首先,你应该从角度发送文件作为多部分形式的数据。您可以通过实现这一点:

​​

发送使用HTTP请求该表单数据的节点服务器。您可以在nodejs中使用express来定义路由和http方法。在angularJS上,请求应该如下所示:

$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

相关问题