Reputation: 383
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
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