Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 从nodejs请求到s3的流响应_Node.js_Amazon S3_Aws Sdk_Requestjs - Fatal编程技术网

Node.js 从nodejs请求到s3的流响应

Node.js 从nodejs请求到s3的流响应,node.js,amazon-s3,aws-sdk,requestjs,Node.js,Amazon S3,Aws Sdk,Requestjs,如何使用aws sdk for node下载文件内容并将其直接流式传输到s3 下面的代码给了我对象#没有方法“read”,这使得请求似乎没有返回可读的流 var req = require('request'); var s3 = new AWS.S3({params: {Bucket: myBucket, Key: s3Key}}); var imageStream = req.get(url) .on('response', function (response) { i

如何使用aws sdk for node下载文件内容并将其直接流式传输到s3

下面的代码给了我
对象#没有方法“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);
        });
      }
    });
});
根据
主体
需要是
可读流
对象

我做错了什么


这可以通过使用模块来实现,但是我更愿意限制我的依赖关系。

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

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);
        });
      }
    });
});

因为我和@JoshSantangelo(S3上的零字节文件)在request@2.60.0和aws-sdk@2.1.43,让我使用Node自己的
http
模块添加一个替代解决方案(注意:简化的代码来自实际项目,未单独测试):

var http=require('http');
函数copyToS3(url、键、回调){
get(url,函数onResponse(res){
如果(res.statusCode>=300){
返回回调(新错误('Error'+res.statusCode+'retrieving'+url));
}
s3.上传({Key:Key,Body:res},回调);
})
.on('error',函数onError(err){
返回回调(err);
});
}
据我所知,问题在于
request
不完全支持当前的Node streams API,而
aws sdk
依赖于此

参考资料:


由于
请求
已被弃用,这里有一个利用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不会引发异常-承诺永远不会解决。

哪里/如何定义了
req
请求?@mscdex问题已更新以反映ReqThank!对于其他引用,请求获取流的文档化方法有点误导我也有同样的问题——这个答案很有用,但s3上的文件最终是零字节。将相同的请求传送到磁盘会产生一个有效的文件。@JoshSantangelo如果您仍然有这个问题,也许可以看看我的替代解决方案。@JoshSantangelo可能太晚了,但可能是您使用了错误的编码。如果不提供编码,则请求假定文本数据,例如图像数据将被损坏。使用req.get({url:url,encoding:null})。零字节看起来很奇怪。你知道如何指定文件存储的名称吗?这是唯一适合我的解决方案。谢谢。这很有效——但我不得不使用https而不是https的httpA简单开关:var http=require('http');var https=require('https');如果(url.toString().indexOf(“https”)==0{http=https;}我正在尝试类似的方法,但这是在测试文件(jest)中运行的。所以代码块被封装在一个
await expect(新承诺((解析,拒绝)=>{
)中。我将代码封装在一个异步函数中,比如So
const resp=async(url)=>{
然后调用
resp
。问题是我最终遇到了超时。你有什么建议吗?我注意到,如果凭据丢失或不工作,AWS sdk不会抛出错误-它只是从来没有响应,所以可能先检查一下。+1这也是我的问题。我希望在碰撞之前知道这一点几天来我一直在想办法解决这个问题。谢谢@skoll