FormData en JavaScript : récupérer et envoyer les champs d'un formulaire

FormData lit tous les champs d'un formulaire en une ligne et part tel quel dans un fetch, fichiers compris. À condition que chaque champ ait un name.
3 min de lecture
Believemy logo

Un formulaire de dix champs, et la tentation de lire chaque valeur une par une avec un sélecteur. Le code fonctionne, puis un champ change de nom et personne ne s'en aperçoit.

Le navigateur sait déjà collecter ces valeurs : c'est ce qu'il fait quand un formulaire part sans JavaScript. Un objet natif donne accès à ce travail.


Définition

FormData représente un ensemble de couples nom et valeur, exactement ceux qu'un formulaire enverrait. Construit à partir d'un élément de formulaire, il en lit tous les champs d'un coup. Construit vide, il se remplit à la main.

JAVASCRIPT
const formulaire = document.querySelector("form");
const donnees = new FormData(formulaire);

console.log(donnees.get("email"));      // "camille@exemple.fr"
console.log(donnees.getAll("interet")); // ["design", "code"]

donnees.append("source", "newsletter");
console.log(Object.fromEntries(donnees));

Un même nom peut porter plusieurs valeurs, ce qu'aucun objet simple ne sait représenter. get rend la première, getAll les rend toutes, et Object.fromEntries ne conserve que la dernière.


Les champs qui n'y sont pas

La collecte suit les règles du HTML, pas celles du code. Quatre catégories de champs sont écartées sans le moindre avertissement.

  • Sans attribut name : un champ qui n'en porte pas n'existe pas pour le formulaire.
  • Désactivé : l'attribut disabled retire le champ de l'envoi.
  • Case non cochée : rien n'est envoyé, il n'y a pas de valeur fausse.
  • Bouton d'envoi : sa valeur n'apparaît que si on le passe en second argument du constructeur.

La première ligne explique la moitié des envois vides signalés en développement : le champ est visible, rempli, et pourtant absent des données.


Envoyer un formulaire, fichiers compris

L'objet part tel quel dans le corps d'un fetch(). C'est le seul moyen simple de transmettre un fichier choisi par un visiteur.

JAVASCRIPT
formulaire.addEventListener("submit", async (evenement) => {
  evenement.preventDefault();

  const reponse = await fetch("/api/inscriptions", {
    method: "POST",
    body: new FormData(formulaire),
  });

  console.log(reponse.ok);
});

L'appel à preventDefault() empêche le rechargement classique de la page, sans quoi le navigateur enverrait le formulaire lui-même.

Bon à savoir

Ne posez jamais l'en-tête Content-Type à la main avec un envoi de ce type. Le navigateur doit y ajouter une frontière calculée qui sépare les champs ; écrite manuellement, elle est fausse et le serveur ne lit plus rien.


Questions fréquentes

Question

Comment envoyer les mêmes données en JSON ?

Convertissez d'abord l'ensemble en objet, puis sérialisez-le : JSON.stringify(Object.fromEntries(donnees)). Attention aux champs à valeurs multiples, qui se réduisent alors à une seule valeur, et aux fichiers, qui ne survivent pas à la conversion. Pour un envoi en paramètres d'URL, new URLSearchParams(donnees) fait le travail directement.


Question

Peut-on lire le contenu du fichier avant l'envoi ?

Oui, la valeur associée à un champ de type fichier est un objet File, avec son nom, sa taille et son type. Ses méthodes text() et arrayBuffer() rendent une promesse sur le contenu, ce qui permet un aperçu ou une vérification de poids avant tout appel réseau.


Question

Pourquoi mon champ apparaît-il deux fois ?

Parce que append ajoute une valeur sans remplacer celles qui existent déjà, contrairement à set qui écrase tout ce qui porte ce nom. Un envoi rejoué après un échec, sur un objet réutilisé, duplique donc les valeurs. Reconstruisez l'objet à chaque tentative plutôt que de le corriger.

Termes connexes

Découvrez notre glossaire JavaScript

Tous les mots de JavaScript expliqués simplement : mots-clés, objets natifs, méthodes, erreurs et concepts. Définitions claires et exemples qui tournent, pour apprendre et pour se dépanner.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.