NodeJS如何从aws s3存储桶下载文件到磁盘?

我的目标:

显示一个对话框,提示用户保存从aws下载的文件。

我的问题:

我目前使用的是awssum-amazon-s3来创build一个下载stream。 然而,我只设法将文件保存到我的服务器或stream到命令行…正如你可以从我的代码看到我的最后一次尝试是尝试手动设置内容处置标题失败。 我不能使用res.download()作为标题已被设置?

我怎样才能达到我的目标?

我的节点代码:

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

我的代码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!'); }); }; 

这个代码的目的是让用户使用一个生成的密钥来下载文件一次。

这是在最新版本的aws-sdk上使用stream式传输的整个代码

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

你已经知道了解决你的问题的最重要的部分:你可以将来自S3的文件stream传递给任何可写的stream,无论是文件stream还是将被发送到客户端的响应stream!

 s3.GetObject(options, { stream : true }, function(err, data) { res.attachment('test.pdf'); data.Stream.pipe(res); }); 

请注意使用res.attachment将设置正确的标题。 您也可以查看关于stream和S3的这个答案 。

这个代码为我最近的图书馆工作:

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