🎯 FormData.append() en résumé
La méthode FormData.append() ajoute une nouvelle paire clé-valeur à un objet FormData existant. Contrairement à set() qui écrase les valeurs, append() conserve les valeurs multiples pour une même clé. Cette méthode est essentielle pour envoyer des fichiers et créer des formulaires multipart en JavaScript.
📝 Syntaxe de base
formData.append(name, value)
formData.append(name, value, filename)
- name : nom du champ (string)
- value : valeur (string, Blob, File)
- filename : nom du fichier (optionnel pour Blob/File)
🔧 Utilisation de base avec des champs texte
L’usage le plus simple de append() consiste à ajouter des données textuelles. La méthode convertit automatiquement les types primitifs en chaînes :
const formData = new FormData();
formData.append('username', 'Kevin');
formData.append('age', 25); // Converti en "25"
formData.append('active', true); // Converti en "true"
formData.append('score', null); // Converti en "null"
📁 Gestion des fichiers
FormData brille particulièrement dans la gestion des fichiers. Voici comment ajouter des fichiers depuis un input HTML :
const fileInput = document.querySelector('#fileInput');
const formData = new FormData();
// Ajout d'un fichier simple
formData.append('avatar', fileInput.files[0]);
// Personnaliser le nom du fichier
formData.append('document', fileInput.files[0], 'rapport_2025.pdf');
// Créer un Blob et l'ajouter
const textBlob = new Blob(['Contenu du fichier'], {type: 'text/plain'});
formData.append('notes', textBlob, 'notes.txt');
📊 Comparaison append() vs set()
| Méthode | Comportement avec clé existante | Cas d’usage |
|---|---|---|
append() |
Ajoute une nouvelle valeur | Upload multiple, tableaux |
set() |
Remplace la valeur existante | Valeurs uniques, mise à jour |
🗂️ Valeurs multiples et tableaux
Pour envoyer plusieurs valeurs sous la même clé (comme des fichiers multiples), utilisez append() plusieurs fois :
const formData = new FormData();
const files = document.querySelector('#multipleFiles').files;
// Méthode classique avec boucle for
for (let i = 0; i < files.length; i++) {
formData.append('photos[]', files[i]);
}
// Méthode moderne avec forEach
Array.from(files).forEach(file => {
formData.append('photos[]', file);
});
// Ajout de valeurs texte multiples
const categories = ['tech', 'AI', 'dev'];
categories.forEach(cat => formData.append('categories[]', cat));
[] après le nom du champ aide les frameworks backend (PHP, Node.js) à reconnaître les données comme un tableau.
🎭 Objets JavaScript et sérialisation
FormData ne gère que les paires clé-valeur plates. Pour les objets complexes, utilisez la sérialisation JSON :
const formData = new FormData();
const userProfile = {
name: 'Kevin',
preferences: {
theme: 'dark',
notifications: true
},
skills: ['JavaScript', 'Python', 'AI']
};
// Sérialisation de l'objet en JSON
formData.append('profile', JSON.stringify(userProfile));
// Le serveur devra parser ce JSON
// Côté serveur : JSON.parse(formData.get('profile'))
🌐 Intégration avec fetch() et envoi
L’avantage de FormData avec l’API fetch est la gestion automatique des en-têtes :
const formData = new FormData();
formData.append('title', 'Mon article');
formData.append('content', 'Contenu de l'article...');
formData.append('image', fileInput.files[0]);
// Envoi avec fetch - pas besoin de définir Content-Type
fetch('/api/articles', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log('Succès:', data))
.catch(error => console.error('Erreur:', error));
Content-Type avec FormData ! Le navigateur le fait automatiquement avec la bonne boundary.
🐛 Débogage et pièges courants
Inspecter le contenu d’un FormData
FormData n’est pas directement lisible dans la console. Utilisez ces méthodes pour déboguer :
const formData = new FormData();
formData.append('test', 'valeur');
// Afficher toutes les paires clé-valeur
for (const [key, value] of formData.entries()) {
console.log(key, value);
}
// Vérifier l'existence d'une clé
console.log(formData.has('test')); // true
// Obtenir toutes les valeurs d'une clé
console.log(formData.getAll('photos[]'));
🚫 Erreurs fréquentes
- Définir Content-Type manuellement : laissez le navigateur faire
- Oublier la sérialisation JSON pour les objets complexes
- Ne pas utiliser [] pour les tableaux côté backend
- Confondre append() et set() pour les valeurs multiples
💼 Exemple complet – Formulaire avancé
Voici un exemple intégrant tous les concepts abordés :
// HTML correspondant
// <form id="advancedForm">
// <input type="text" name="title" value="Mon projet IA">
// <input type="file" name="documents" multiple>
// <input type="file" name="avatar">
// <select name="tags" multiple>...</select>
// </form>
document.getElementById('advancedForm').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData();
// Données texte
formData.append('title', this.title.value);
formData.append('created_at', new Date().toISOString());
// Fichiers multiples
Array.from(this.documents.files).forEach(file => {
formData.append('documents[]', file);
});
// Fichier unique avec nom personnalisé
if (this.avatar.files[0]) {
formData.append('avatar', this.avatar.files[0], 'profile.jpg');
}
// Données complexes (objet métadonnées)
const metadata = {
version: '1.0',
author: 'Kevin',
technologies: ['JavaScript', 'FormData', 'Fetch API']
};
formData.append('metadata', JSON.stringify(metadata));
// Tags multiples
const selectedTags = Array.from(this.tags.selectedOptions).map(opt => opt.value);
selectedTags.forEach(tag => formData.append('tags[]', tag));
// Envoi
fetch('/api/projects', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) throw new Error('Erreur réseau');
return response.json();
})
.then(data => {
console.log('Projet créé:', data);
// Traiter la réponse
})
.catch(error => {
console.error('Erreur lors de l'envoi:', error);
// Gérer l'erreur
});
});
🔄 Alternatives et cas d’usage
Quand utiliser FormData ?
- ✅ Upload de fichiers
- ✅ Formulaires multipart
- ✅ Données mixtes (texte + fichiers)
- ✅ Compatibilité avec les formulaires HTML
Quand utiliser URLSearchParams ?
- ✅ Données texte uniquement
- ✅ Format application/x-www-form-urlencoded
- ✅ APIs RESTful simples
// URLSearchParams pour données simples
const params = new URLSearchParams();
params.append('name', 'Kevin');
params.append('role', 'developer');
fetch('/api/user', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params
});
📚 Résumé des bonnes pratiques
✅ À faire :
- Utiliser
append()pour les valeurs multiples - Ajouter
[]aux noms de champs pour les tableaux - Sérialiser les objets avec
JSON.stringify()) - Laisser le navigateur gérer le Content-Type
- Gérer les erreurs avec try/catch ou .catch()
❌ À éviter :
- Définir manuellement les en-têtes multipart
- Oublier de convertir FileList en Array
- Utiliser FormData pour des données JSON pures
- Négliger la validation côté client
❓ FAQ - Questions fréquentes
Peut-on modifier une valeur déjà ajoutée avec append() ?
Non, append() ajoute toujours une nouvelle valeur. Utilisez set() pour remplacer ou delete() puis append() pour modifier.
FormData fonctionne-t-il avec tous les navigateurs ?
Oui, FormData est supporté par tous les navigateurs modernes depuis IE10+. La méthode append() est disponible partout où FormData l'est.
Comment envoyer un FormData avec XMLHttpRequest ?
const xhr = new XMLHttpRequest();
xhr.open('POST', '/upload');
xhr.send(formData); // Pas besoin de setRequestHeader
Peut-on cloner un objet FormData ?
Il n'y a pas de méthode native clone(), mais vous pouvez recréer un FormData :
const newFormData = new FormData();
for (const [key, value] of originalFormData.entries()) {
newFormData.append(key, value);
}
Comment gérer les gros fichiers avec FormData ?
FormData gère les gros fichiers automatiquement, mais considérez :
- Upload en chunks pour les très gros fichiers
- Progress events avec XMLHttpRequest
- Timeouts ajustés côté serveur
FormData peut-il envoyer des données nested (imbriquées) ?
Non directement. Utilisez la notation à points ou sérialisez en JSON :
// Notation à points
formData.append('user.name', 'Kevin');
formData.append('user.email', 'kevin@example.com');
// Ou JSON
formData.append('user', JSON.stringify({name: 'Kevin', email: 'kevin@example.com'}));
Sources externes utiles :