Upload to S3 - The body of your POST request is not well-formed multipart/form-data

Viewed 18

I am trying to upload a file to s3 using this guide: https://www.dtreelabs.com/blog/s3-direct-file-upload-using-presigned-url-from-react-and-rails which long story short describes how to use a presigned url to upload files to S3.

Whenever I send the request to my s3 bucket to upload a given file, I am getting an error The body of your POST request is not well-formed multipart/form-data.

My front end code is:

  const handleImageUpload = (file) => {
    ApiUtils.getPresignedS3Url({ fileName: file.name }).then((uploadParams) => {
      if (uploadParams) {
        uploadToS3(uploadParams, file)
      }
    })

 const uploadToS3 = (uploadParams, file) => {
    const { url, s3_upload_params: fields } = uploadParams
    const formData = new FormData()
    formData.append("Content-Type", file.type)
    Object.entries(fields).forEach(([k, v]) => {
      formData.append(k, v)
    })
    formData.append("file", file)
    fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "multipart/form-data",
      },
      undefined,
      body: formData,
    })
      .then((awsResponse) => {
        if (awsResponse.ok) {
          console.log("success")
        } else {
          console.log(awsResponse)
        }
      })
      .catch((error) => {
        console.log("blew up")
        console.log(error)
      })
  }

Several other stack overflow answers involve using Axios or new XMLHttpRequest. These have resulted in the same error for me.

the end of the payload I am sending to amazon is:

------WebKitFormBoundary7cFRTGgKGqbDhagf
Content-Disposition: form-data; name="file"; filename="uploadMe.html"
Content-Type: text/html


------WebKitFormBoundary7cFRTGgKGqbDhagf--

I believe the issue may be something along the lines of the body of my file isn't being included in the request. I'm investigating this now.

Any help would be appreciated, thank you <3

1 Answers

https://github.com/github/fetch/issues/505#issuecomment-293064470 describes why this is an issue. Posting the text incase the comment ever gets removed:

Setting the Content-Type header manually means it's missing the boundary parameter. Remove that header and allow fetch to generate the full content type. It will look something like this:

Content-Type: multipart/form-data;boundary=----WebKitFormBoundaryyrV7KO0BoCBuDbTL

Fetch knows which content type header to create based on the FormData object passed in as the request body content.

removing "Content-Type": "multipart/form-data" above indeed seems to result in the mujltipart form data being formatted correctly.

Related