Node.js 从nodejs请求到s3的流响应
如何使用aws sdk for node下载文件内容并将其直接流式传输到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
对象#没有方法“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(新承诺((解析,拒绝)=>{
)中。我将代码封装在一个异步函数中,比如Soconst resp=async(url)=>{
然后调用resp
。问题是我最终遇到了超时。你有什么建议吗?我注意到,如果凭据丢失或不工作,AWS sdk不会抛出错误-它只是从来没有响应,所以可能先检查一下。+1这也是我的问题。我希望在碰撞之前知道这一点几天来我一直在想办法解决这个问题。谢谢@skoll