POST form data using JavaScript’s Fetch API
Last updated: August 24, 2022.
Using JavaScript’s Fetch API to send form data gives you full control of data transmission.
Rather than relying on standard HTML behavior, which immediately sends the data payload upon submit and redirects to a new page, you can handle the data transmission in the background and communicate the result efficiently through minimal DOM manipulation.
Best of all, this process is made extremely easy by in-built constructor objects in JavaScript that do most of the heavy lifting.
Table of contents
Prerequisites
Form setup
To demonstrate, we need a form.
Let’s keep things simple: a form with an id of form
with which we can select it in JavaScript. The form contains two input fields named username
and password. Make sure to give the inputs identifiable names because these will be the keys through which data values can be identified in the payload.
Finally, there is a button of type submit
that will submit the form data as a submit event.
<!--- HTML form data ---> <form id="form"> <input name="username" type="text"> <input name="password "type="password"> <button type="submit">Submit</button> </form>
Add a form submit event listener
First, select the form element and add an event listener to it, listening out for a submit event. And inside the function, apply the preventDefault()
method to the event object to prevent the form being submitted by HTML by default.
/* Selecting the HTML form and adding a 'submit' event listener */ const form = document.getElementById('form'); form.addEventListener('submit', function(e) { e.preventDefault() })
Sending the form data
Option #1: As FormData object
The in-built FormData
object constructor will help you do all the heavy lifting.
Pass in a form element to it, and it will convert its contents into arrays of data (one for each form element) containing two items: an element’s name
attribute and the value input for the element.
Because the object produced is a special FormData
object with associated methods, you cannot view its payload contents directly with console.log()
. Instead, access the contained data directly using console.log([…payload])
.
/* Converting the form to a new formData object */ const form = document.getElementById('form'); form.addEventListener('submit', function(e) { // Prevent default behavior: e.preventDefault(); // Create payload as new FormData object: const payload = new FormData(form); console.log([…payload]); })
Now, you can send the form data as a POST request using the Fetch API. We use the test server httpbin.org to make the request. It responds by sending back the request’s parameters, which is fine for testing purposes.
Importantly, do not create a Content-Type
property in the options object passed in to the fetch request in the second position. This will be determined automatically as multipart/form-data
(the norm for HTML forms). Entering an erroneous value could lead to an error.
/* Sending the formData object as payload using Fetch */ const form = document.getElementById('form'); form.addEventListener('submit', function(e) { // Prevent default behavior: e.preventDefault(); // Create payload as new FormData object: const payload = new FormData(form); // Post the payload using Fetch: fetch('https://httpbin.org/post', { method: 'POST', body: payload, }) .then(res => res.json()) .then(data => console.log(data)) })
Option #2: As a URL-enconded string
You can also send the form data as a URL-encoded string. This i more efficient for text-based form data.
For this, you can also lean heavily on an in-built object constructor: URLSearchParams
. Pass in a FormData
object, and it will convert it to a URL-encoded string that you can then send as the payload.
/* Converting the form to a URL-encoded string */ const form = document.getElementById('form'); form.addEventListener('submit', function(e) { // Prevent default behavior e.preventDefault(); // Create new FormData object: const formData = new FormData(form); // Convert formData object to URL-encoded string: const payload = new URLSearchParams(formData); })
The fetch request to send the payload is exactly the same as above. But this time, it will be sent as content type application/x-www-form-urlencoded
. You do not need to enter a Content-Type
property, as this will be set automatically.
/* Sending the URL-encoded string as payload using Fetch */ const form = document.getElementById('form'); form.addEventListener('submit', function(e) { // Prevent default behavior: e.preventDefault(); // Create new FormData object: const formData = new FormData(form); // Convert formData object to URL-encoded string: const payload = new URLSearchParams(formData); // Post the payload using Fetch: fetch('https://httpbin.org/post', { method: 'POST', body: payload, }) .then(res => res.json()) .then(data => console.log(data)) })
For this type of payload, the browser will decode what is sent for you to view it in developer tools. For this, access (in Chrome) the Network > Fetch/XHR. Now select the post item in this view and view the Payload tab. It should look something like this:

Summary
Using JavaScript's Fetch API to submit form data gives you full flexibility over the data transmission process, rather than relying upon the default form submission behavior of HTML.
Related links
- MDN Web Docs: URLSearchParams
- MDN Web Docs: FormData