从nodejs请求到s3的流响应

时间:2015-06-17 21:38:16

标签: node.js amazon-s3 aws-sdk requestjs

如何使用request下载文件内容并使用节点的aws-sdk直接将其流式传输到s3?

下面的代码给了我Object #<Request> has no method 'read',这看起来似乎请求没有返回可读的流......

var req = require('request');
var s3 = new AWS.S3({params: {Bucket: myBucket, Key: s3Key}});
var imageStream = req.get(url)
    .on('response', function (response) {
      if (200 == response.statusCode) {
        //imageStream should be read()able by now right?
        s3.upload({Body: imageStream, ACL: "public-read", CacheControl: 5184000}, function (err, data) {  //2 months
          console.log(err,data);
        });
      }
    });
});

根据aws-sdk docs Body需要成为ReadableStream个对象。

我在这里做错了什么?

可以使用s3-upload-stream模块撤消此操作,但我更愿意限制我的依赖项。

3 个答案:

答案 0 :(得分:11)

由于我遇到与@JoshSantangelo(S3上的零字节文件)相同的问题,请求request@2.60.0和aws-sdk@2.1.43,让我添加一个使用Node自己的{{1模块(警告:来自现实生活项目的简化代码,未单独测试):

http

据我所知,问题是var http = require('http'); function copyToS3(url, key, callback) { http.get(url, function onResponse(res) { if (res.statusCode >= 300) { return callback(new Error('error ' + res.statusCode + ' retrieving ' + url)); } s3.upload({Key: key, Body: res}, callback); }) .on('error', function onError(err) { return callback(err); }); } 并不完全支持当前的Node流API,而request依赖于它。

参考文献:

答案 1 :(得分:6)

如果您手动侦听响应流,则需要使用response对象:

var req = require('request');
var s3 = new AWS.S3({params: {Bucket: myBucket, Key: s3Key}});
var imageStream = req.get(url)
    .on('response', function (response) {
      if (200 == response.statusCode) {
        s3.upload({Body: response, ACL: "public-read", CacheControl: 5184000}, function (err, data) {  //2 months
          console.log(err,data);
        });
      }
    });
});

答案 2 :(得分:0)

不推荐使用Request,这是利用Axios的解决方案

const AWS = require('aws-sdk');
const axios = require('axios');

const downloadAndUpload = async function(url, fileName) {
  const res = await axios({ url, method: 'GET', responseType: 'stream' });
  const s3 = new AWS.S3(); //Assumes AWS credentials in env vars or AWS config file
  const params = {
    Bucket: IMAGE_BUCKET, 
    Key: fileName,
    Body: res.data,
    ContentType: res.headers['content-type'],
  };
  return s3.upload(params).promise();
}

请注意,如果AWS凭证错误或缺失,当前版本的AWS开发工具包(SDK)不会引发异常-诺言根本无法解决。