I'm having trouble reading a file via FileReader
and properly uploading it to S3 via PutObject
without the file being corrupted.
Description of problem
I've been using MongoDB Stitch as my serverless platform with my app, and it comes built-in with an S3 service provider. I can correctly upload text files, but if I try to upload any binary file (Excel, PDF, images, etc.) and download it straight from my S3 bucket and open it in its respective program, my computer reports it as corrupted.
I've looked at both files, the original on my computer and the one uploaded to S3, and they're very similar, but it seems some data was changed in the upload.
Current attempts
I'm using FileReader
to open a reading stream and FileReader.readAsBinaryString()
to read the file. My ContentType
in the headers is set to the original file type (e.g. for .txt
, text/plain
; for .jpg
, .jpeg
) via File.type
.
I've seen that the W3C recommends using FileReader.readAsArrayBuffer()
instead of readAsBinaryString()
, but S3 reports an error when trying to upload the resulting data: value for field "Body" should be of type "io.ReadSeeker"
.
I've also tried FileReader.readAsDataURL()
, but I don't know of a way to convert the base64 URL for any file type back to its original format. The only examples I can find all involve using base64 to encode/decode images.
Code
const readFile = (file) => {
return new Promise((resolve) => {
const fileReader = new FileReader()
fileReader.onload = (event) => {
resolve(event.target.result)
}
fileReader.readAsBinaryString(file)
})
}
async s3Upload(file) {
const fileData = await readFile(file)
const putObjectArgs = {
Body: fileData,
Key: file.name,
ContentType: file.type,
ACL: 'public-read',
Bucket: 'BUCKET_NAME',
}
// call the Stitch services to upload
}
Question
Is there a way to upload any type of file to S3 in the same way it's stored in my filesystem? or a generic method to encode/decode any file type to/from base64?