I think this should be a straight forward thing, but I can't fing a solution :s
I'm trying to figure out the best way to show images stored on amazon S3 on a website.
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. This can be done by using the .pipe()
function of a stream.
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.
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. When the request to S3 closes, this will automatically end the res
of express.
For more information about streams, refer to substack's excellent Stream Handbook.
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.
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. 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.
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);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With