Explain Codes LogoExplain Codes Logo

How do I post form data with fetch api?

javascript
fetch-api
form-data
async-await
Anton ShumikhinbyAnton Shumikhin·Feb 13, 2025
TLDR

To submit form data with the Fetch API, create a FormData object and pass it to fetch with method set to 'POST'. Check out an express example:

const form = new FormData(document.querySelector('#myForm')); fetch('/submit', { method: 'POST', body: form }) .then(response => response.json()) // Gotcha! Got the response. .then(console.log) // Woohoo! Logged the result. .catch(console.error); // Oops! Something went wrong.

This approach works great for straightforward form submissions without the fuss of additional header configurations.

Encoding FormData to URLSearchParams

If your use case requires data in application/x-www-form-urlencoded format, a more efficient method of data transmission, it's best to encode your FormData instance into URLSearchParams:

// Preparing a ✨secret message✨ to send const formData = new FormData(document.querySelector('#yourForm')); const searchParams = new URLSearchParams(); for (const pair of formData) { // Whispering data secrets into the params' ears searchParams.append(pair[0], pair[1]); } // What's the magic word? 'Fetch'! fetch('/submit', { method: 'POST', body: searchParams }) .then(response => response.json()) // Abracadabra! What's in the response? .then(data => console.log(data)) // Ta-da! Here's the secret data! .catch(error => console.error(error)); // Uh-oh! The magic trick failed.

This method efficiently encodes the form data to URLSearchParams, providing an optimized way to interact with Fetch API for data transmission.

Adjusting fetch headers for URLSearchParams

When manually constructing a URLSearchParams object, remember to set the correct Content-Type to 'application/x-www-form-urlencoded':

fetch('/submit', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' // Because manners matter, always ask nicely! }, body: searchParams });

Such a meticulous header statement can lead your server and client to the ballroom of smooth API communication.

Manual efforts with form data

Need more control over your form data? Engineered to the rescue, use the HTMLFormElement.elements to iterate:

const formElement = document.querySelector('#yourForm'); const data = {}; for (const element of formElement.elements) { if (element.name) { data[element.name] = element.value; } } // DIYing some searchParams const searchParams = new URLSearchParams(data); // Knock! Knock! Special delivery for the server! fetch('/submit', { method: 'POST', body: searchParams });

This manual approach gives you the right amount of control over form data serialization and debugging, not to mention some adrenaline rush of DIYing it.

Securing form

While orchestrating forms on the web, remember to conduct the CSRF tokens through your orchestra for a security-filled performance:

formData.append('csrf_token', 'yourCsrfTokenHere');

Appending a CSRF token to the form data enhances the security while submitting scripts via fetch.

Map client-side with server expectations

Ensure your JavaScript form serialization melodiously harmonizes with the server-side model expectation:

// Server expects a duet: // { // "name": "John Doe", // "age": 30 // } // Your form data should know the tune formData.append('name', 'John Doe'); formData.append('age', '30');

This will guarantee an impeccable server-client concerto, keeping your server-side symphony in sync with your client-side tunes.

Asynchronous response handling

The heavy metal band of async/await can rock the house down when it comes to dealing with fetch responses:

async function submitForm(formElement) { const formData = new FormData(formElement); try { const response = await fetch('/submit', { method: 'POST', body: formData }); const data = await response.json(); console.log(data); // Drop the mic 🎤 } catch (error) { console.error(error); // Well, the real rock stars improvise this! } } submitForm(document.querySelector('#yourForm'));

Such asynchronous power chords produce a melanious symphony of clean syntax, advanced error handling, and versatile state management.

Debug with network

Monitor your network requests in your browser's development tools to debug and validate your data transmission.

Shunning jQuery

Evolved are the times into embracing modern JavaScript over the need for jQuery for form serialization:

// Saying goodbye 😔 $('#yourForm').serialize(); // Saying hello 😄 new URLSearchParams(new FormData(document.querySelector('#yourForm'))).toString();

Choosing Fetch API and FormData objects over jQuery reduces the client-side dependencies without compromising on functional power.

Adapt to dynamic form fields

With forms adapting to dynamic fields, just add fields on-the-fly to the FormData object:

formData.append('newField', 'newValue');

Embrace the dynamicity and power your forms to the future with Fetch API.

Have fun with FormData.entries()

Using FormData.entries(), transform form data into an array of key-value pairs to manipulate them easily before sending off to your back-end.

Direct form submission control

Want to control the form submission yourself? Then break the default form submission behavior free:

formElement.addEventListener('submit', function(event) { event.preventDefault(); // Now play fetch! });

With the power to control in your hands, fetch the form data and direct it for a more complex client-side control.