FormData and URLSearchParams on form-urlencoded in XHR

explain my motivation

I think FormData API is very useful when I send File via XHR in multipart/form-data. but in case of sending text key-value to server, it’s better to send with them in x-www-form-urlencoded body.

for example from http://www.html5rocks.com/ja/tutorials/file/xhr2/

function sendForm() {
  var formData = new FormData();
  formData.append('username', 'johndoe');
  formData.append('id', 123456);

  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/server', true);
  xhr.onload = function(e) { ... };

  xhr.send(formData);
}

in this case, payload became a multipart/form-data. and I think a lot of server receiving like these data, expects x-www-form-urlencoded. (ex. many of oauth server)

of course we can do that via URLSearchParams. but how about this case ?

from http://www.html5rocks.com/ja/tutorials/file/xhr2/

<form id="myform" name="myform" action="/server">
  <input type="text" name="username" value="johndoe">
  <input type="number" name="id" value="123456">
  <input type="submit" onclick="return sendForm(this.form);">
</form>
function sendForm(form) {
  var formData = new FormData(form);

  formData.append('secret_token', '1234567890'); // Append extra data before send.

  var xhr = new XMLHttpRequest();
  xhr.open('POST', form.action, true);
  xhr.onload = function(e) { ... };

  xhr.send(formData);

  return false; // Prevent page from submitting.
}

this is very convenient, but we can’t do that with URLSearchParams(means x-www-form-urlencoded).

opinion

I guess this design based on "blob can’t send via x-www-form-urlencoded so how about think about way to send Form which only includs “form-urlencodable texts” via x-www-form-urlencoded ?

idea1: URLSearchParams construct with Form

var params = new URLSearchParams(document.getElementById("text-only-form"));
xhr.send(params.toString());

idea2: get URLSearchParams from FormData.

var params = new FormData(form).params; // get from FormData
var params = new URLSearchParams(formData); // construct with FormData

idea3: send FormData with form-urlencodable text only falls back to x-www-form-urlencoded no multipar/form-data

var formData = new FormData();
formData.append('username', 'johndoe');
formData.append('id', 123456);
xhr.send(formData); // x-www-formurlencoded

idea4: xhr2 respects Content-Type header

I think sending XHR ignores content-type header when sending FormData. so respect it.

xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
var formData = new FormData();
formData.append('username', 'johndoe');
formData.append('id', 123456);
xhr.send(formData); // x-www-formurlencoded

if FormData includes Blob props, one of fallback way is encode in BASE64 for example.

wrapup

I wanna send form-urlencoded using URLSearchParams or FormData construct from plain text only .

thanks and sorry for my poor english ;p

Jxck

Sounds like a good library to write! I hope you write it and share it here!

Yes, please!

So tired of having to half ass implement form serialization in various libraries. This would really help obsolete the need for $.serializeArray

The extended FormData APIs now being implemented might help here.

https://chromium.googlesource.com/chromium/blink/+/0f4632bca55675b72e3e03a8d231c2e879276a02

I’m really hoping this is eventually covered by browser api. Defining helps explain how the existing form serialization process already works. @domenic hoping you get around to "<form> as a custom element" soon to hit all these pain points :wink:

So this is basically asking for new URLSearchParams(HTMLFormElement) correct? I filed https://www.w3.org/Bugs/Public/show_bug.cgi?id=27941 to get this in the specification. Makes sense to me to get parity with FormData.

:heart_eyes: I would love that.

Yes that seems cool :slight_smile:

Has a solution ever been made to the above? I tried do a for(var name in formData) and all I get is the members of the FormData class: append, etc.