我认为这应该是一个直截了当的事情,但我无法解决问题: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" />
是不是可以直接从亚马逊展示图像? 我的意思是,减轻我服务器负载的解决方案将是最好的。
答案 0 :(得分:11)
这是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
。
有关流的更多信息,请参阅substack的优秀Stream Handbook。
PS:注意,在你的代码片段中你有两个名为res
的变量:内部变量将掩盖外部变量,这可能导致很难找到错误。
答案 1 :(得分:6)
如果您正确设置了访问控制(基于每个键,而不是整个Bucket。)那么您可以使用<img src="http://aws.amazon.com/myBucket/myKey/moreKey.jpg">
(或者如果您使用的不是我们的其他内容,则使用其他适当的域名 - 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);
});