私の目標:
Awsからダウンロードするファイルを保存するようユーザーに促すダイアログボックスを表示します。
私の問題:
現在、ダウンロードストリームを作成するためにawssum-Amazon-s3を使用しています。しかし、ファイルをサーバーに保存するか、コマンドラインにストリームすることしかできませんでした...私のコードからわかるように、最後の試みは失敗したコンテンツ処理ヘッダーを手動で設定することでした。ヘッダーが既に設定されているため、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!');
});
角度の私のコード:
$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!');
});
};
このコードの目的は、ユーザーが生成されたキーを使用してファイルを1回ダウンロードできるようにすることです。
これは、最新バージョンの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);
});
このコードは、最新のライブラリで機能しました:
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);
}
});
問題を解決するために最も重要なことはすでにわかっています。S3からのファイルストリームを、書き込み可能なストリームにパイプすることができます。
s3.GetObject(options, { stream : true }, function(err, data) {
res.attachment('test.pdf');
data.Stream.pipe(res);
});
res.attachment
を使用すると、正しいヘッダーが設定されることに注意してください。また、ストリームとS3について この回答 も確認できます。