Search code examples
aws-lambdaxmlhttprequestform-data

How to avoid multipart/form-data with XMLHTTPRequest and FormData


I'm trying to setup an html form, the form action is an aws lambda function. When I submit the form via plain html, all is well. However, when I'm sending the form via XMLHTTPRequest + FormData the lambda function breaks.

Looking at the lambda logs it seems that when using the plain html form send, the form is encoded in the request body as straight forward query string ('name=Johnny&email=john%40bon.com' etc) which my lambda function can parse. However, when using XMLHTTPRequest+FormData to send the form, the form is encoded in using a different format which I believe (not sure) is called multipart/form-data (has these WebKitFormBoundaryXXX additions).

Is there a way to make XMLHTTPRequest+FormData send the form in the same format as is used when sending the form via plain html. Alternatively, how to do parse this multipart/form-data format in aws lambda python.

    const form = document.querySelector('#my-form-id')
    form.addEventListener('submit', event => {
      // disable default action
      event.preventDefault()

      // configure a request
      const xhr = new XMLHttpRequest()
      xhr.open('POST', 'www.myurl.com/submit')

      // prepare form data
      let data = new FormData(form)

      // set headers
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

      // send request
      xhr.send(data)

      // listen for `load` event
      xhr.onload = () => {
        console.log(xhr.responseText)
      }
      })```



Solution

  • Is there a way to make XMLHTTPRequest+FormData send the form in the same format as is used when sending the form via plain html.

    Well. It does… for a value of plain HTML with enctype='multipart/form-data'.

    If you want to send application/x-www-form-urlencoded data then FormData is the wrong tool for the job.

    Use URLSearchParams instead.

    You can initialise it with a FormData object.

    const data = new URLSearchParams(new FormData(document.querySelector('form')));
    console.log(`${data}`);
    <form>
        <input name=foo value=bar>
        <input name=x value=y>
    </form>

    Note that XMLHttpRequest can infer the Content-Type header when you pass a URLSearchParams or FormData object to send() so don't set it manually. That is just a waste of time and an opportunity to introduce errors.