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.

  const form = event.target;

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

 * 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;
  • \$\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
    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\$ 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
    Nov 24, 2018 at 9:38
  • \$\begingroup\$ @Calak The solution you linked to is not more robust or flexible than mine. \$\endgroup\$ Nov 24, 2018 at 9:40

1 Answer 1


Can this generalization be simplified further?

return new URLSearchParams(formData)
  • 1
    \$\begingroup\$ Oh, great! Since formData[Symbol.iterator] returns formData.entries(), it can be omitted from that call, too. \$\endgroup\$ 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\$ Nov 26, 2018 at 8:12
  • \$\begingroup\$ @kleinfreund Have not tried Safari or Edge \$\endgroup\$ 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
    Nov 28, 2018 at 15:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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