0

I need to upload an image directly to an S3 bucket. I am using react native, and react-native-image-picker to select a photo. This returns a local image uri. Here is my code right now.

ImagePicker.showImagePicker(options, response => {
    var bodyFormData = new FormData(); // If I don't use FormData I end up 
                                       // uploading the json not an image
    bodyFormData.append('image', {
        uri: response.uri, // uri rather than data to avoid loading into memory
        type: 'image/jpeg'
    });

    const uploadImageRequest = {
        method: 'PUT',
        url: presignedS3Url,
        body: bodyFormData,
        headers: {
            'Content-Type: 'multipart/form-data'
        }
    };

    axios(uploadImageRequest);
});

This almost works.. when I check my S3 bucket I have a file thats nearly an image. It has the following format

--Y_kogEdJ16jhDUS9qhn.KjyYACKZGEw0gO-8vPw3BcdOMIrqVtmXsdJOLPl6nKFDJmLpvj^M
content-disposition: form-data; name="image"^M
content-type: image/jpeg^M
^M
<Image data>

If I manually go in and delete the header, then I have my image! However, I need to be uploading an image directly to S3, which clients will be grabbing and expecting to already be in a proper image format.

I can make this work using response.data and decoding to a string and uploading that directly, but for the sake of memory I'd rather not do this.

1 Answers1

1

Upload image to S3 from client using AJAX with presigned URL

It's been a while since you posted your question so I guess you already found a solution, but anyway... I was trying to do the same, i.e. upload an image to S3 using axios, but I just wasn't able to make it work properly. Fortunately, I found out that we can easily do the trick with plain AJAX:

const xhr = new XMLHttpRequest();
xhr.open('PUT', presignedS3Url);
xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
       if (xhr.status === 200) {
          console.log('Image successfully uploaded to S3');
       } else {
           console.log('Error while sending the image to S3.\nStatus:', xhr.status, "\nError text: ", xhr.responseText);
        }
    }  
}
xhr.setRequestHeader('Content-Type', 'image/jpeg');
xhr.send({ uri: imageUri, type: 'image/jpeg', name: fileName});

This code is taken from this really useful article which borrows from this blog.

RdC1965
  • 412
  • 5
  • 8