NodeJS Как загрузить файл на диск из ведра aws s3?

Моя цель:

Отобразите диалоговое окно, предлагающее пользователю сохранить файл, загружаемый с aws.

Моя проблема:

В настоящее время я использую awssum-amazon-s3 для создания потока загрузки. Однако мне удалось сохранить файл на моем сервере или передать его в командную строку... Как вы можете видеть из моего кода, моя последняя попытка состояла в том, чтобы попытаться вручную установить заголовки несоответствий содержимого, которые не удались. Я не могу использовать res.download(), поскольку заголовки уже установлены?

Как я могу достичь своей цели?

Мой код для 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!');
    });

Мой код для 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!');
        });
    };

Цель этого кода - позволить пользователям использовать сгенерированный ключ для загрузки файла один раз.

Ответы

Ответ 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);
});

Ответ 2

Вы уже определились с тем, что наиболее важно для решения вашей проблемы: вы можете передавать поток файлов, поступающий из S3, в любой записываемый поток, будь то поток... или поток ответов, который будет отправлен клиенту!

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

Обратите внимание на использование res.attachment, в котором будут установлены правильные заголовки. Вы также можете проверить этот ответ относительно потоков и S3.

Ответ 3

Этот код работал у меня с самой последней библиотекой:

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