ryandonohue
ryandonohue

Reputation: 189

Display image from s3

I am trying to display images that I have uploaded to S3. I believe the permissions are correct as I can hit the url and get data back. However when I put the URL in an image tag I get a broken link.

When I put the image tag on my site in the network tab I see the call to s3 (with a 200 response) but an empty body. If I hit the s3 url directly I get the data back and in the network tab I see the call WITH a response body from s3.

I'm uploading the images from a Vue frontend to an express/node backend. I see the images fine in s3.

s3.putObject({
    Bucket: 'MYBUCKET',
    Key: `${result._id}-${file.upload.filename}`,
    Body: file.dataURL,
    ACL: 'public-read',
    ContentType: 'binary',
    ContentEncoding: 'utf8'
}, function (resp) {});

Fiddle: https://jsfiddle.net/Xadvz/7327/

I use the data I get back from hitting s3 directly and it displays the image but when I put in the s3 url it displays a broken link.

Upvotes: 1

Views: 2601

Answers (2)

zer00ne
zer00ne

Reputation: 43910

Are you sure Content-Type: 'binary' is correct? The value is identical to MIME type. Here's some typical types:

*.jpg .................................. image/jpeg

*.html ................................. text/html

*.txt ..................................... text/plain

*.mp3 .................................. audio/mpeg

Unknown/Default .............. application/octet-stream

Content-Type values must conform to the same syntax as MIME type:

type/sub-type

If you aren't sure you should at least use application/octet-stream

Upvotes: 1

Paul Tsai
Paul Tsai

Reputation: 1009

S3 does not support dataURL data format.

In your backend:

  1. convert dataURL to buffer
  2. set ContentType of S3 object according to dataURL

code:

var regex = /^data:.+\/(.+);base64,(.*)$/;

var matches = file.dataURL.match(regex);
var ext = matches[1]; // image/jpeg
var data = matches[2]; // base64 string

var buffer = new Buffer(data, 'base64');

s3.putObject({
    Bucket: 'MYBUCKET',
    Key: `${result._id}-${file.upload.filename}`,
    Body: buffer, // upload binary
    ACL: 'public-read',
    ContentType: ext // set content type
}, function (resp) {});

Upvotes: 2

Related Questions