6

我认为这应该是一件直截了当的事情,但我无法找到解决方案:s

我试图找出在网站上显示存储在亚马逊 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" />

是不是可以直接从亚马逊显示图像?我的意思是,减轻服务器负载的解决方案将是最好的。

4

2 回答 2

13

这是的典型用例。您要做的是:从 Amazon S3 请求文件并将该请求的答案(即图像)直接重定向到客户端,而不存储临时文件。这可以通过使用.pipe()流的功能来完成。

我假设您用于查询 Amazon S3 的库返回一个流,正如您已经使用的那样.on('data'),and.on('end')是流对象的标准事件。

您可以这样做:

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

通过使用管道,我们将向 S3 的请求输出直接重定向到客户端。当对 S3 的请求关闭时,这将自动结束resexpress。

有关流的更多信息,请参阅 substack 优秀的Stream Handbook

PS:请注意,在您的代码片段中,您有两个名为res的变量:内部变量将掩盖外部变量,这可能导致难以找到错误。

于 2013-11-09T22:02:37.077 回答
7

如果您正确设置了访问控制(在每个密钥的基础上。而不是在整个存储桶上。)那么您可以在<img src="http://aws.amazon.com/myBucket/myKey/moreKey.jpg">任何您想要的地方使用(或者如果您使用的是 us-east-1 以外的其他东西,则可以使用另一个适当的域)在您的 html 中显示图像。如果您希望浏览器显示图像而不是在有人打开图像时将图像下载为附件,请记住设置 MIME 类型。

aws-sdk 文档
s3:PUT 对象文档

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);
});
于 2013-11-10T07:37:44.880 回答