2013-11-09 2 views
4

Я думаю, что это должно быть прямо вперед вещь, но я не могу Fing решение: Sпоказывает изображение из амазонок s3 с nodejs, expressjs и Нокс

Я пытаюсь выяснить, лучший путь к показывать изображения, хранящиеся на амазонке S3 на веб-сайте.

В настоящее время я пытаюсь получить эту работу (неудачный)

//app.js 
app.get('/test', function (req, res) { 
    var file = fs.createWriteStream('slash-s3.jpg'); 
    client.getFile('guitarists/cAtiPkr.jpg', function(err, res) { 
     res.on('data', function(data) { file.write(data); }); 
     res.on('end', function(chunk) { file.end(); }); 
    }); 
}); 

//index.html 
<img src="/test" /> 

Разве не может быть, можно показать изображения непосредственно из амазонки? Я имею в виду, что решение, облегчающее загрузку на моем сервере, было бы лучшим.

ответ

9

Это типичный вариант использования для streams. То, что вы хотите сделать, это: запросить файл с Amazon S3 и перенаправить ответ этого запроса (то есть изображение) непосредственно на клиент, не сохраняя временный файл. Это можно сделать, используя функцию потока .pipe().

Я предполагаю, что библиотека, которую вы используете для запроса, Amazon S3 возвращает поток, поскольку вы уже используете .on('data') и .on('end'), которые являются стандартными событиями для объекта потока.

Вот как вы можете это сделать:

app.get('/test', function (req, res) { 
    client.getFile('guitarists/cAtiPkr.jpg', function(err, imageStream) { 
     imageStream.pipe(res); 
    }); 
}); 

Используя трубу, мы перенаправить вывод запроса на S3 непосредственно клиенту. Когда запрос на S3 закрывается, это автоматически закончит res экспресс.

Дополнительную информацию о потоках см. В превосходном Stream Handbook.

PS: Будьте осторожны, в вашем фрагменте кода у вас есть две переменные с именем res: внутренняя переменная будет маскировать внешнюю переменную, которая может привести к затруднению поиска ошибок.

+0

спасибо !! работал сразу. прямо к клиенту? идеально!! – coiso

+1

Ваш сервер делает фактический запрос, но он не сохранит результат в файле и вместо этого напрямую напишет вывод в гнездо клиента. Это очень эффективно и позволяет оптимизировать оптимизацию, см. Руководство по потоку для обзора основных потоков. –

+0

Как вы можете применить этот метод при потоковой передаче нескольких изображений? Например, потоковое много изображений на новый канал пользователя, как Facebook. – c0mrade

6

, если вы правильно настроили элементы управления доступом (на основе каждой клавиши, а не на весь Bucket.), Вы можете просто использовать <img src="http://aws.amazon.com/myBucket/myKey/moreKey.jpg"> (или другой соответствующий домен, если вы используете что-то другое, кроме us-east-1), где бы вы ни хотели отображать изображение в своем html. не забудьте установить тип MIME, если вы хотите, чтобы браузеры отображали изображение вместо загрузки изображения в виде вложения, когда кто-то его открывает.

aws-sdk docs
s3: PUT Object docs

var AWS = require('aws-sdk'); 
AWS.config.update({ 
    accessKeyId: "something", 
    secretAccessKey: "something else", 
    region:'us-east-1', 
    sslEnabled: true, 
}); 
var fileStream = fs.createReadStream(filename); 
s3.putObject({ 
    Bucket:'myBucket', 
    Key: 'myKey/moreKey.jpg', 
    Body: fileStream, 
    ContentType:'image/jpeg', 
    ACL: 'public-read', 
}, function(err, data){ 
    if(err){ return callback(err) }; 
    console.log('Uploaded '+key); 
    callback(null); 
}); 
Смежные вопросы