将来自 nodejs 请求的响应流式传输到 s3
stream response from nodejs request to s3
如何使用 request 下载文件内容并使用 aws-sdk for node 直接将其流式传输到 s3?
下面的代码给了我 Object #<Request> has no method 'read'
这使得请求看起来不是 return 可读流...
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 模块来实现,但是我更愿意限制我的依赖性。
如果您手动侦听响应流,您希望使用 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);
});
}
});
});
由于我在 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
不完全支持当前的节点流 API,而 aws-sdk
依赖它。
参考文献:
由于 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 不会抛出异常 - 承诺根本无法解决。
如何使用 request 下载文件内容并使用 aws-sdk for node 直接将其流式传输到 s3?
下面的代码给了我 Object #<Request> has no method 'read'
这使得请求看起来不是 return 可读流...
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 模块来实现,但是我更愿意限制我的依赖性。
如果您手动侦听响应流,您希望使用 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);
});
}
});
});
由于我在 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
不完全支持当前的节点流 API,而 aws-sdk
依赖它。
参考文献:
由于 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 不会抛出异常 - 承诺根本无法解决。