NodeJS 如何从 aws s3 存储桶将文件下载到磁盘?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22143628/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NodeJS How do I Download a file to disk from an aws s3 bucket?
提问by gbachik
My goal:
我的目标:
Display a dialog box prompting the user to save a file being downloaded from aws.
显示一个对话框,提示用户保存从 aws 下载的文件。
My problem:
我的问题:
I am currently using awssum-amazon-s3 to create a download stream. However I've only managed to save the file to my server or stream it to the command line... As you can see from my code my last attempt was to try and manually set the content disposition headers which failed. I cannot use res.download() as the headers have already been set?
我目前正在使用 awssum-amazon-s3 创建下载流。但是,我只设法将文件保存到我的服务器或将其流式传输到命令行...正如您从我的代码中看到的那样,我的最后一次尝试是尝试手动设置失败的内容处置标头。我不能使用 res.download() 因为标题已经设置了?
How can I achieve my goal?
我怎样才能实现我的目标?
My code for node:
我的节点代码:
app.post('/dls/:dlKey', function(req, res, next){
// download the file via aws s3 here
var dlKey = req.param('dlKey');
Dl.findOne({key:dlKey}, function(err, dl){
if (err) return next(err);
var files = dl.dlFile;
var options = {
BucketName : 'xxxx',
ObjectName : files,
};
s3.GetObject(options, { stream : true }, function(err, data) {
// stream this file to stdout
fmt.sep();
data.Headers['Content-Disposition'] = 'attachment';
console.log(data.Headers);
data.Stream.pipe(fs.createWriteStream('test.pdf'));
data.Stream.on('end', function() {
console.log('File Downloaded!');
});
});
});
res.end('Successful Download Post!');
});
My code for angular:
我的角度代码:
$scope.dlComplete = function (dl) {
$scope.procDownload = true;
$http({
method: 'POST',
url: '/dls/' + dl.dlKey
}).success(function(data/*, status, headers, config*/) {
console.log(data);
$location.path('/#!/success');
}).error(function(/*data, status, headers, config*/) {
console.log('File download failed!');
});
};
The purpose of this code it to let users use a generated key to download a file once.
这段代码的目的是让用户使用生成的密钥下载文件一次。
回答by Yash Dayal
This is the entire code using streaming on the latest version of aws-sdk
这是在最新版本的 aws-sdk 上使用流的完整代码
var express = require('express');
var app = express();
var fs = require('fs');
app.get('/', function(req, res, next){
res.send('You did not say the magic word');
});
app.get('/s3Proxy', function(req, res, next){
// download the file via aws s3 here
var fileKey = req.query['fileKey'];
console.log('Trying to download file', fileKey);
var AWS = require('aws-sdk');
AWS.config.update(
{
accessKeyId: "....",
secretAccessKey: "...",
region: 'ap-southeast-1'
}
);
var s3 = new AWS.S3();
var options = {
Bucket : '/bucket-url',
Key : fileKey,
};
res.attachment(fileKey);
var fileStream = s3.getObject(options).createReadStream();
fileStream.pipe(res);
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('S3 Proxy app listening at http://%s:%s', host, port);
});
回答by SebastianView
This code worked for me with the most recent library:
这段代码对我来说适用于最新的库:
var s3 = new AWS.S3();
var s3Params = {
Bucket: 'your bucket',
Key: 'path/to/the/file.ext'
};
s3.getObject(s3Params, function(err, res) {
if (err === null) {
res.attachment('file.ext'); // or whatever your logic needs
res.send(data.Body);
} else {
res.status(500).send(err);
}
});
回答by Paul Mougel
You've already figured what's most important to solve your issue: you can pipe the file stream coming from S3 to any writable stream, be it a filestream… or the response stream that will be sent to the client!
您已经知道解决问题最重要的是什么:您可以将来自 S3 的文件流通过管道传输到任何可写流,无论是文件流……还是将发送到客户端的响应流!
s3.GetObject(options, { stream : true }, function(err, data) {
res.attachment('test.pdf');
data.Stream.pipe(res);
});
Note the use of res.attachmentthat will set the correct headers. You can also check out this answerregarding streams and S3.
请注意,使用res.attachment它会设置正确的标题。您还可以查看有关流和 S3 的答案。
回答by Swetabja Hazra
Simply create a ReadStream from S3 and WriteStream to the location were u want to download. Find the code below. Works perfectly for me:
只需从 S3 和 WriteStream 创建一个 ReadStream 到您要下载的位置。找到下面的代码。非常适合我:
var AWS = require('aws-sdk');
var path = require('path');
var fs = require('fs');
AWS.config.loadFromPath(path.resolve(__dirname, 'config.json'));
AWS.config.update({
accessKeyId: AWS.config.credentials.accessKeyId,
secretAccessKey: AWS.config.credentials.secretAccessKey,
region: AWS.config.region
});
var s3 = new AWS.S3();
var params = {
Bucket: '<your-bucket>',
Key: '<path-to-your-file>'
};
let readStream = s3.getObject(params).createReadStream();
let writeStream = fs.createWriteStream(path.join(__dirname, 's3data.txt'));
readStream.pipe(writeStream);

