10

您如何使用request下载文件内容并使用 aws-sdk for node 将其直接流式传输到 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 文档 Body需要是一个ReadableStream对象。

我在这里做错了什么?

这可以使用s3-upload-stream模块完成,但是我更愿意限制我的依赖项。

4

3 回答 3

12

由于我在 request@2.60.0 和 aws-sdk@2.1.43 遇到了与@JoshSantangelo(S3 上的零字节文件)相同的问题,让我使用 Node 自己的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);
    });
}

据我所知,问题在于request它不完全支持当前的 Node 流 API,而aws-sdk依赖于它。

参考:

于 2015-08-08T11:44:42.480 回答
7

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);
        });
      }
    });
});
于 2015-06-18T18:16:29.333 回答
1

正如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 开发工具包不会引发异常 - 承诺永远不会解决。

于 2020-07-21T09:54:16.047 回答