kush patel
kush patel

Reputation: 21

Is there a way to upload image as binary data on pre-signed s3 PUT url using Axios or XHR

1) Code to generate s3 URL

      const file = req.files ? req.files.filename || null : null
      const extension = path.extname(file.name)
      const client = new S3Client()

      const params = {
        Bucket: S3_BUCKET, // env variable
        Key: `tmp/photos/image_file.png`,
        ContentDisposition: 'inline',
        ContentType: file.mimetype,
        Body: file.data
      }

      const command = new PutObjectCommand(params)
      const presignedS3Url = await getSignedUrl(client, command, { expiresIn: 3600 })

I am able to upload image with this CURL request

curl --location --request PUT $presignedS3Url \
--header 'Content-Disposition: inline' \
--header 'Content-Type: image/png' \
--data-binary '@/Users/name/Downloads/image-file.png'

Not able to upload using axios

      const imageFile = fs.readFile('/Users/filepath/image-file.png')
      const bufferString = Buffer.from(imageFile, 'base64')

      await axios.put(presignedS3Url, {
        data: bufferString
      }, {
        headers: {
          'Content-Type': file.mimetype,
          'Content-Disposition': 'inline'
        }
      })

How to use Axios or XHR to upload image?

Upvotes: 0

Views: 1351

Answers (2)

kush patel
kush patel

Reputation: 21

While generating presigned URL use this

    const params = {
        Bucket: S3_BUCKET, // env variable
        Key: `tmp/photos/image_file.png`
      }

To upload use XMLHttpRequest

    const s3Url = uploadedImageResponse?.item?.url || ''
    const xhr = new XMLHttpRequest()
    xhr.withCredentials = false

    xhr.upload.onprogress = event => {
      if (event.lengthComputable) {
        const percentComplete = (event.loaded / event.total) * 100
        progressHandler(percentComplete, fileName)
      }
    }
    xhr.onreadystatechange = async function () {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          await successHandler(uploadedImageResponse, fileName)
        } else {
          errorHandler('Error uploading file', fileName)
        }
      }
    }
    xhr.open('PUT', s3Url)
    xhr.send(file.file)

Upvotes: 0

Dinozzo
Dinozzo

Reputation: 1021

Hope this helps

  const fs = require('fs/promises');
  const imageFile = fs.readFile('/Users/filepath/image-file.png')

  await axios.put(presignedS3Url, imageFile, {
    headers: {
      'Content-Type': file.mimetype
    }
  })

Upvotes: 1

Related Questions