Preparing form data for a POST request with fetch Acquiring a form’s data for asynchronous POST requests has been a long-standing problem. There is the FormData API, but there are still some obstacles when the form’s data is encoded as x-www-form-urlencoded (the default).

My current use case deals with arbitrary forms which might encode data either way; hence, I tried to generalize the way I construct the request’s body. Note that it’s intentional the form is submitted as an asynchronous request as the response is going to be rendered inside the current document.

Can this generalization be simplified further?

document.querySelector('form').addEventListener('submit', performPostRequest);

/**
 * Handles submit events that are about to perform a POST request.
 *
 * @param {Event} event
 */
function performPostRequest(event) {
  // Prevent the default action of sending a regular POST request.
  event.preventDefault();

  const form = event.target;

  fetch(form.action, {
    method: 'post',
    headers: {
      'Content-Type': `${form.enctype}; charset=UTF-8`
    },
    body: constructRequestBody(form)
  })
    .then(console.log)
    .catch(console.error);
}

/**
 * Encodes a form’s data for a POST request’s body.
 *
 * Supported encoding types:
 *
 * - `application/x-www-form-urlencoded`
 * - `multipart/form-data`
 *
 * @param {HTMLFormElement} form
 * @returns {FormData|URLSearchParams}
 */
function constructRequestBody(form) {
  const formData = new FormData(form);

  if (form.enctype === 'multipart/form-data') {
    return formData;
  }

  const requestBody = new URLSearchParams();

  for (const [name, value] of formData) {
    requestBody.append(name, value);
  }

  return requestBody;
}
Can this generalization be simplified further?


return new URLSearchParams(formData)