简体   繁体   English

用nodejs,expressjs和knox显示亚马逊s3的图像

[英]showing an image from amazon s3 with nodejs, expressjs and knox

I think this should be a straight forward thing, but I can't fing a solution :s 我认为这应该是一个直截了当的事情,但我无法解决问题:s

I'm trying to figure out the best way to show images stored on amazon S3 on a website. 我正在试图找出在网站上显示存储在亚马逊S3上的图像的最佳方式。

Currently I'm trying to get this to work (unsuccessful) 目前我正试图让它工作(不成功)

//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" />

Isn't it maybe possible to show the images directly from amazon ? 是不是可以直接从亚马逊展示图像? I mean, the solution that lightens the load on my server would be the best. 我的意思是,减轻我服务器负载的解决方案将是最好的。

This is a typical use case for streams . 这是的典型用例。 What you want to do is: request a file from Amazon S3 and redirect the answer of this request (ie. the image) directly to the client, without storing a temporary file. 您要做的是:从Amazon S3请求文件并将此请求的答案(即图像)直接重定向到客户端,而不存储临时文件。 This can be done by using the .pipe() function of a stream. 这可以通过使用流的.pipe()函数来完成。

I assume the library you use to query Amazon S3 returns a stream, as you already use .on('data') and .on('end') , which are standard events for a stream object. 我假设您用于查询Amazon S3的库返回一个流,因为您已经使用.on('data').on('end') ,它们是流对象的标准事件。

Here is how you can do it: 以下是如何做到这一点:

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

By using pipe, we redirect the output of the request to S3 directly to the client. 通过使用管道,我们将请求的输出直接重定向到S3到客户端。 When the request to S3 closes, this will automatically end the res of express. 当S3的请求关闭时,这将自动结束快递的res

For more information about streams, refer to substack's excellent Stream Handbook . 有关流的更多信息,请参阅substack的优秀流手册

PS: Be careful, in your code snippet you have two variables named res : the inner variable will mask the outer variable which could lead to hard to find bugs. PS:注意,在你的代码片段中你有两个名为res的变量:内部变量将掩盖外部变量,这可能导致很难找到错误。

if you set the access controls correctly (on a per-key basis. not on the whole Bucket.) then you can just use <img src="http://aws.amazon.com/myBucket/myKey/moreKey.jpg"> (or another appropriate domain if you're using something other than us-east-1) wherever you want to display the image in your html. 如果您正确设置访问控制(基于每个键,而不是整个Bucket。)那么您可以使用<img src="http://aws.amazon.com/myBucket/myKey/moreKey.jpg"> (或其他适当的域名,如果你使用的不是us-east-1),无论你想在html中显示图像。 remember to set the MIME type if you want browsers to display the image instead of downloading the image as attachment when someone opens it. 如果您希望浏览器显示图像而不是在有人打开图像时将图像作为附件下载,请记住设置MIME类型。

aws-sdk docs aws-sdk docs
s3: PUT Object docs 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);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM