0
\$\begingroup\$

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;
}
\$\endgroup\$
4
  • \$\begingroup\$ (Repost, link fixed) "there are still some obstacles when the form’s data is encoded as x-www-form-urlencoded" can you explain? Does this resolve potential problems? \$\endgroup\$
    – Calak
    Commented Nov 24, 2018 at 9:29
  • \$\begingroup\$ @Calak I’m referring to the problem I’m solving in the constructRequestBody function: Using a FormData object for a POST request with x-www-form-urlencoded data. The answer in the link you provided solves the problem, but it is more verbose. \$\endgroup\$ Commented Nov 24, 2018 at 9:33
  • \$\begingroup\$ Does the relative verbosity is a real problem if your ending code is more robust and flexible? \$\endgroup\$
    – Calak
    Commented Nov 24, 2018 at 9:38
  • \$\begingroup\$ @Calak The solution you linked to is not more robust or flexible than mine. \$\endgroup\$ Commented Nov 24, 2018 at 9:40

1 Answer 1

1
\$\begingroup\$

Can this generalization be simplified further?

return new URLSearchParams(formData)
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Oh, great! Since formData[Symbol.iterator] returns formData.entries(), it can be omitted from that call, too. \$\endgroup\$ Commented Nov 26, 2018 at 8:07
  • \$\begingroup\$ Do you know whether this is implemented in most browsers? I tried Firefox and Chrome and it does work. \$\endgroup\$ Commented Nov 26, 2018 at 8:12
  • \$\begingroup\$ @kleinfreund Have not tried Safari or Edge \$\endgroup\$ Commented Nov 26, 2018 at 8:21
  • \$\begingroup\$ As of writing this comment only IE11 (and below) and some other browsers do not support URLSearchParams. Check here: caniuse.com/#feat=urlsearchparams \$\endgroup\$
    – Shion
    Commented Nov 28, 2018 at 15:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.