user2689931
user2689931

Reputation: 383

Upload image to S3 using presigned URL

I've been having a hell of a time getting a simple test to work. I am working on a mobile app in react native. I want to generate a presigned URL and use that url to upload a video file to s3. I'm currently just trying to test this approach by doing:

const file = fs.readFileSync('./video.mp4')
s3.getSignedUrl('putObject', {Bucket: 'mybucket', Key: 'video.mp4'}, (err, url) => {
  if (err) { console.log(err); }
  else {
    fetch(url, {
       method: 'PUT',
       body: file
    })
    .then(success => console.log(success.status))
    .catch(e => console.log(e))
  })
})

I get a 200 status code, but the 'file' that appears on S3 has 0 bytes. I noticed the same thing happens when I try to upload ANY file that I received via fs.readFileSync. I managed to work around this temporarily be doing fs.readFileSync('./video.mp4', 'base64'), but this won't work in my app, because I need to access the video in it's original format, not as a base64 string. I also successfully used s3.upload, but that won't work in my app either, because I want to authenticate all my user's actions on my server before I give them permission to do an interaction with s3. I'd really appreaciate some advice. I've been fiddling around with ContentTypes and ContentLengths all day.

Upvotes: 6

Views: 13141

Answers (1)

Yi Feng Xie
Yi Feng Xie

Reputation: 5027

You need to use FormData to wrap your file with parameter named file like following:

var body = new FormData();
body.append('file', file);
fetch(url, { method: 'PUT', body: body });

Upvotes: 17

Related Questions