Node.js 直接从节点js req body加载文件到S3

Node.js 直接从节点js req body加载文件到S3,node.js,amazon-web-services,amazon-s3,sails.js,Node.js,Amazon Web Services,Amazon S3,Sails.js,我正在尝试使用Node.jsAmazonWebServicesdk将文件上载到s3,并尝试直接从请求主体中选择要上载到Amazon上的文件。但是,我一直得到一个类型错误:buf.copy不是一个函数。下面是我的代码: create: function(req, res) { var imageFile = req.file('imageFile'); var fileName = Math.floor(Date.now() / 1000); var key = sett

我正在尝试使用
Node.js
AmazonWebService
sdk将文件上载到s3,并尝试直接从请求主体中选择要上载到Amazon上的文件。但是,我一直得到一个
类型错误:buf.copy不是一个函数。下面是我的代码:

 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 基本副本(缓冲区、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) 在endReadableNT(_stream_readable.js:905:12) 在下一次使用2args进行回调时(node.js:455:9) 在进程中。_tickDomainCallback(node.js:410:17)


我不确定
req.file('imageFile')
返回什么,但您应该将一个流设置为AWS.S3 params的Body字段。 比如:

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

我不确定
req.file('imageFile')
返回什么,但您应该将一个流设置为AWS.S3 params的Body字段。 比如:

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

从节点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;
}

从节点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;
}

req.file('imageFile')
是从
sails req
传递的参数,因此,它指向主体中的多部分参数。我不想在上传到S3之前先上传到我的服务器,我明白了……好吧,我想这样或那样,它会间接上传到你的服务器上——也许不是在磁盘上,而是在内存中。无论如何,检查sails的“file”文档时,我注意到.file(…:)以“对象模式”返回一个流。我认为“对象模式”流可能是您遇到的问题。以下是sails文档中的内容:“通常,流只在字符串和缓冲区上运行。处于对象模式的流可以发出除缓冲区和字符串以外的通用JavaScript值。”
req.file('imageFile')
是从
sails req
传递的参数,因此,它指向主体中的多部分参数。我不想在上传到S3之前先上传到我的服务器,我明白了……好吧,我想这样或那样,它会间接上传到你的服务器上——也许不是在磁盘上,而是在内存中。无论如何,检查sails的“file”文档时,我注意到.file(…:)以“对象模式”返回一个流。我认为“对象模式”流可能是您遇到的问题。这是来自sails文档的“通常情况下,流只在字符串和缓冲区上运行。处于对象模式的流可以发出除缓冲区和字符串以外的通用JavaScript值。”这有点令人困惑,但sails将所有
req.file
调用视为流,这意味着当文件,你似乎没有使用任何一个,你只是将
imageFile
直接传递给S3的上传处理程序,它不是一个文件,而是一个缓冲区?仅供参考:你也可以直接从浏览器上传文件到S3,而不必触摸你的服务器。我知道。但是,回答一个问题?看这里,我看到我可以上传一个文件,它将在
.tmp
中暂时保留一段时间。我只是想知道它是否会被删除。因为,看着我的
.tmp
我可以看到我已经尝试了3天的所有测试。包括那些我用SkipperS3上传的。但是,skipper s3仅限于
s3.amazon.com
我不知道Sails在内部做什么,但在该链接中有一个示例显示了其中一个事件处理程序,以及您需要如何等待文件实际上载,然后才能将其发送到其他地方。是的。谢谢现在我明白了,这有点让人困惑,但是Sails将所有
req.file
调用都视为流,这意味着在文件上传、已经上传和完成上传等时会有事件和回调。您似乎不使用任何事件和回调,只需将
imageFile
直接传递给S3的上传处理程序,它不是一个文件,而是一个缓冲区?仅供参考:你也可以直接从浏览器上传文件到S3,而不必触摸你的服务器。我知道。但是,回答一个问题?看这里,我看到我可以上传一个文件,它将在
.tmp
中暂时保留一段时间。我只是想知道它是否会被删除。因为,看着我的
.tmp
我可以看到我已经尝试了3天的所有测试。包括那些我用SkipperS3上传的。但是,skipper s3仅限于
s3.amazon.com
我不知道Sails在内部做什么,但在该链接中有一个示例显示了其中一个事件处理程序,以及您需要如何等待文件实际上载,然后才能将其发送到其他地方。是的。谢谢现在我明白了。非常感谢。这是在2016年。我已经忘了那个帖子了。非常感谢。这是在2016年。我已经忘了那个帖子了。