将文件直接从Node js req body加载到S3

时间:2016-02-03 07:56:17

标签: node.js amazon-web-services amazon-s3 sails.js

我正在尝试使用Node.js Amazon Web Service sdk将文件上传到s3,我尝试直接从请求正文中选择文件以在Amazon上传。但是,我一直在TypeError: buf.copy is not a function。以下是我的代码:

 create: function(req, res) {
    var imageFile = req.file('imageFile');
    var fileName = Math.floor(Date.now() / 1000);
    var key = settings.aws.Key;
    var secret = settings.aws.Secret;
    var bucket = settings.aws.Bucket;
    AWS.config.update({accessKeyId: key, secretAccessKey: secret});
    var parames = {Bucket: bucket, Key: fileName, Body: imageFile};
    var s3Obj = new AWS.S3();
    s3Obj.upload(parames).
    on('httpUploadProgress', function(evt) {console.log("In "+evt.loaded); }).
    send(function(err, data){
        if (err) {
            return ValidationService.jsonResolveError(err, Inventory, res);
        }
        console.log(data);
        res.json({status:200, file: data});
    })
}

我不断得到的错误的更详细的堆栈跟踪:

  

buffer.js:237       buf.copy(buffer,pos);           ^

     

TypeError:buf.copy不是函数       在Function.Buffer.concat(buffer.js:237:9)       在ManagedUpload.fillStream(/node_modules/aws-sdk/lib/s3/managed_upload.js:389:21)       在上游。 (/node_modules/aws-sdk/lib/s3/managed_upload.js:172:28)       在emitNone(events.js:67:13)       在Upstream.emit(events.js:166:7)       at endReadableNT(_stream_readable.js:905:12)       at nextTickCallbackWith2Args(node.js:455:9)       at process._tickDomainCallback(node.js:410:17)

2 个答案:

答案 0 :(得分:1)

我不确定req.file('imageFile')返回什么,但您应该设置一个流到AWS.S3 params'身体领域。 类似的东西:

var fileStream = fs.createReadStream(filePath);
fileStream.on('open', () => {
    //your existing S3 initialisation code...
     var parames = {Bucket: bucket, Key: fileName, Body: fileStream};

答案 1 :(得分:0)

从节点8开始,您可以使用async / await并将文件从本地目录流式传输到S3,如下所示:

async function uploadFile(filePath, folderPath)
{
  const readStream = fs.createReadStream(filePath);

  const writeStream = new stream.PassThrough();
  readStream.pipe(writeStream);

  var fname = path.basename(filePath);

  var params = {
        Bucket : 's3-bucket-name',
        Key : folderPath+'/'+fname,
        Body : writeStream
    }

  let uploadPromise = new Promise((resolve, reject) => {
    s3.upload(params, (err, data) => {
      if (err) {
        //logger.error('upload error..', err);
        reject(err);
      } else {
        //logger.debug('upload done..');
        resolve(data);
      }
    });
  });

  var res = await uploadPromise;
  return res;
}