Formular senden ohne Neuladen der Seite
Ein Formular lässt sich im Hintergrund senden, ohne eine neue Seite zu laden, und das Ergebnis dem Benutzer sofort anzeigen. Wie das mit FormData und fetch geht, wie Sie die im Browser eingebaute Formularvalidierung nutzen und wie Sie eine eigene Regel hinzufügen.
Das Formular
<form id="contact" action="/contact.php" method="post"> <input type="email" name="email" required> <textarea name="message" required minlength="10"></textarea> <button type="submit">Senden</button> <p id="result" aria-live="polite"></p> </form>
Der Browser prüft die Attribute required, type="email" und minlength selbst: Ein Formular mit einem Fehler sendet er nicht und zeigt am Feld eine Erklärung an. Das Attribut aria-live sorgt dafür, dass ein Screenreader das Ergebnis des Sendens vorliest.
Senden mit fetch
const form = document.querySelector("#contact");
form.addEventListener("submit", async (event) => {
event.preventDefault();
const button = form.querySelector('button[type="submit"]');
const result = document.querySelector("#result");
button.disabled = true;
try {
const response = await fetch(form.action, { method: "POST", body: new FormData(form) });
if (!response.ok) {
throw new Error("Der Server meldet den Fehler " + response.status);
}
result.textContent = "Vielen Dank, die Nachricht wurde gesendet.";
form.reset();
} catch (error) {
result.textContent = "Die Nachricht konnte nicht gesendet werden. Bitte versuchen Sie es noch einmal.";
} finally {
button.disabled = false;
}
});
- Das Ereignis submit tritt erst ein, wenn das Formular die Prüfung des Browsers bestanden hat. preventDefault verhindert dann das klassische Absenden mit Neuladen der Seite.
- FormData sammelt alle Felder des Formulars (einschließlich eines versteckten Feldes mit dem CSRF-Token und Dateien). PHP bekommt sie in $_POST und $_FILES genauso wie beim normalen Absenden.
- Die Schaltfläche ist während des Sendens deaktiviert, damit ein ungeduldiger Benutzer das Formular nicht zweimal sendet.
- Bei einem Fehler bleiben die eingegebenen Daten im Formular, und der Benutzer kann das Senden wiederholen.
Eine eigene Validierungsregel
<input type="password" id="password" required minlength="10"> <input type="password" id="password2" required>
const password = document.querySelector("#password");
const password2 = document.querySelector("#password2");
password2.addEventListener("input", () => {
password2.setCustomValidity(password2.value === password.value ? "" : "Die Passwörter stimmen nicht überein.");
});
setCustomValidity mit einem Text markiert das Feld als ungültig, und der Browser zeigt den Text beim Versuch des Absendens an. Ein leerer Text hebt den Fehler auf. Die Formularvalidierung lässt sich auch von Hand starten: form.checkValidity() gibt true oder false zurück, form.reportValidity() zeigt zusätzlich die Fehlermeldungen an.
Validierung gehört auch auf den Server
Die Validierung im Browser ist nur eine Bequemlichkeit für den Benutzer – sie lässt sich ausschalten oder umgehen, und eine Anfrage kann man auch ohne Browser senden. PHP muss deshalb dieselben Regeln ebenfalls prüfen. Ein Formular, das Daten ändert, braucht außerdem ein CSRF-Token.
Verwandte Artikel:
Daten laden mit fetch und async/await
Formulare gegen CSRF schützen