Signatur
Beschreibung
Der Konstruktor FormData() erzeugt einen Satz aus Schlüssel-Wert-Paaren, der Formularfelder abbildet. Das Objekt lässt sich direkt als body an fetch() oder XMLHttpRequest.send() übergeben. Es wird dann im Format multipart/form-data übertragen, und zwar mit genau der Kodierung, die auch ein normales Absenden des Formulars erzeugen würde.
Übergibst du ein HTMLFormElement, liest der Konstruktor alle erfolgreichen Steuerelemente (successful controls) ein. Das sind Felder mit name-Attribut, die nicht deaktiviert sind. Bei Checkboxen und Radiobuttons zählen nur ausgewählte, bei Mehrfachauswahl kommt jede gewählte Option als eigener Eintrag hinzu. Dateifelder liefern File-Objekte. Ohne Argument entsteht ein leeres Objekt, das du mit append() oder set() selbst befüllst.
Mit dem optionalen zweiten Parameter submitter nimmt der Konstruktor auch den Absende-Button auf, der das Formular abgeschickt hat, samt name und value. Das hilft, wenn ein Formular mehrere Absende-Buttons hat, zum Beispiel „Speichern“ und „Löschen“. Typischer Einsatz: im submit-Ereignis mit event.submitter.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $form | HTMLFormElement | Formular-Element, dessen aktuelle Feldwerte übernommen werden. Ohne Angabe entsteht ein leeres FormData-Objekt. |
|
| $submitter | HTMLButtonElement | HTMLInputElement | Absende-Button des Formulars. Sein name/value wird aufgenommen. Er muss zu form gehören und ein Absende-Button sein, sonst wird ein TypeError bzw. NotFoundError geworfen. |
Rückgabewert
FormData-Objekt: leer oder vorbefüllt mit den Formularfeldern.Beispiele
Leeres FormData manuell befüllen und hochladen
const fileInput = document.querySelector('#avatar');
const data = new FormData();
data.append('username', 'anna');
data.append('avatar', fileInput.files[0]);
const res = await fetch('/api/profil', {
method: 'POST',
body: data // Content-Type wird automatisch inkl. boundary gesetzt
});
console.log(res.status);
Formular per fetch absenden (inklusive Absende-Button)
const form = document.querySelector('#kontakt');
form.addEventListener('submit', async (event) => {
event.preventDefault();
// submitter übernimmt z. B. name="aktion" value="speichern"
const data = new FormData(form, event.submitter);
const res = await fetch(form.action, { method: 'POST', body: data });
console.log(res.ok ? 'Gesendet' : 'Fehler');
});
Formularinhalt als Objekt bzw. Query-String auslesen
const form = document.querySelector('#suche');
const data = new FormData(form);
for (const [key, value] of data) {
console.log(`${key}: ${value}`);
}
// Einfache Umwandlung (bei Mehrfachwerten gewinnt der letzte)
const obj = Object.fromEntries(data);
console.log(JSON.stringify(obj));
// Für GET-Anfragen
const query = new URLSearchParams(data).toString();
console.log(query);
// Wichtig · Fallstricke
- Keinen
Content-Type-Header selbst setzen: Setzt du beifetchmanuellmultipart/form-data, fehlt derboundary-Parameter, und der Server kann den Body nicht auswerten. Lass den Browser das erledigen. - Felder ohne
name-Attribut sowie deaktivierte Felder (disabled) werden nicht übernommen. Schreibgeschützte Felder (readonly) dagegen schon. - Ohne
submitterfehlt der Wert des geklickten Buttons, anders als beim nativen Absenden des Formulars. Den Parametersubmitterunterstützen erst neuere Browser (Chrome 112, Firefox 111, Safari 16.4). - Der Konstruktor erstellt eine Momentaufnahme: Spätere Änderungen am Formular wirken sich nicht auf das Objekt aus.
Object.fromEntries(formData)verliert Mehrfachwerte, etwa bei mehreren Checkboxen mit gleichem Namen. Nutze dafürformData.getAll(name).FormDatagibt es auch in Web Workern und nativ in Node.js ab Version 18, dort aber ohne Formular-Argument.