AJAX-Kontaktformular

Dieselben Kontaktfelder, per fetch als JSON gesendet. Der Besucher bleibt auf der Seite und sieht einen kurzen Status.

Was Sie kopieren

Diese Vorlage sendet dieselben Kontaktfelder mit fetch, sodass der Besucher auf Ihrer Seite bleibt und einen kurzen Status liest.

Das Formular hat weiterhin eine Aktion und die Methode POST. Wenn JavaScript nicht läuft, führt der Browser stattdessen ein normales Absenden aus.

Dieser Rückfall ist wichtig für ältere Browser und für Menschen, die Skripte blockieren. Sie müssen dafür nicht zwei Formulare pflegen.

Das Haupt-Snippet sendet JSON. Es setzt Content-Type auf application/json und Accept auf application/json.

Erfolg ist der Wahrheitswert success im JSON. Wenn er true ist, zeigt das Snippet die Nachricht der Antwort oder einen kurzen Dank und setzt das Formular zurück.

Wenn er false ist, zeigt das Snippet die Nachricht der Antwort. Formgong schreibt diese Nachricht in der Sprache von _lang.

JSON und FormData

Ein JSON-Body muss die Felder aufführen, die Sie senden möchten. Das Snippet enthält access_key, _lang, name, email, phone, message und botcheck.

Wenn Sie Turnstile später aus dem Kommentar nehmen, kopiert der JSON-Weg auch cf-turnstile-response, sobald dieses Feld einen Wert hat.

Das zusätzliche Snippet nutzt FormData statt JSON. Den Content-Type setzt der Browser, einschließlich der Boundary. Setzen Sie Content-Type nicht selbst.

FormData übernimmt jedes Feld im Formular, einschließlich eines Turnstile-Tokens, wenn das Widget im Formular steht.

Beide Wege senden Accept: application/json. Ohne diesen Header erhält ein normales Absenden aus dem Browser die Danke-Seite und nicht JSON.

Senden Sie nicht zugleich einen JSON-Body und einen Multipart-Body. Wählen Sie einen von beiden. Die beiden Snippets sind Alternativen, keine Schichten.

Spam, Telegram und Grenzen

Lassen Sie das Honeypot mit dem Namen botcheck leer und außerhalb des Bildschirms, mit tabindex -1. Ein ausgefülltes Honeypot wird als Spam gespeichert und nicht zugestellt.

Die Feldnamen bleiben kurz, damit Telegram sie fett setzen kann. Benennen Sie email nicht in einen langen Satz um.

Der Zugriffsschlüssel bleibt auf der Seite. Ihn in ein Geheimnis auf einem Server zu verschieben macht das Formular nicht sicherer, und dieses Snippet hat keinen Server.

Im Free-Tarif ist Telegram sofort, und die E-Mail ist eine tägliche Übersicht. Der Posteingang behält Einsendungen 30 Tage.

Der Free-Tarif umfasst 300 Einsendungen im Monat. Eine Spam-Einsendung verbraucht keine davon.

Diese Vorschau sendet nichts ab. Binden Sie das Snippet auf Ihrer Website ein, und senden Sie danach einen Test von dieser Seite.

Formgong betreibt den Dienst. Wenn Sie Hilfe zum Produkt brauchen, schreiben Sie an support@formgong.com.

Vorschau

Formularcode

HTML
<form id="fg-ajax" action="https://formgong.com/submit" method="POST" style="position:relative">
  <input type="hidden" name="access_key" value="fk_your_access_key">
  <input type="hidden" name="_lang" value="de">
  <label>Name <input type="text" name="name" autocomplete="name" required></label>
  <label>E-Mail <input type="email" name="email" autocomplete="email" required></label>
  <label>Telefon <input type="tel" name="phone" autocomplete="tel"></label>
  <label>Nachricht <textarea name="message" required></textarea></label>
  <div aria-hidden="true" style="position:absolute;inset-inline-start:0;top:0;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)">
  <label>Lassen Sie dieses Feld leer <input type="text" name="botcheck" tabindex="-1" autocomplete="off"></label>
</div>
  <!--
Optional. Schalten Sie Turnstile für dieses Formular ein, entfernen Sie diese Kommentarzeichen und fügen Sie den Site-Key ein.
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<div class="cf-turnstile" data-sitekey="YOUR_TURNSTILE_SITE_KEY" data-language="de"></div>
-->
  <button type="submit">Senden</button>
  <p data-status role="status"></p>
</form>
<script>
(function () {
  var form = document.getElementById("fg-ajax");
  if (!form) return;
  var status = form.querySelector("[data-status]");
  form.addEventListener("submit", function (event) {
    event.preventDefault();
    var data = {
      access_key: form.access_key.value,
      _lang: form._lang.value,
      name: form.name.value,
      email: form.email.value,
      phone: form.phone.value,
      message: form.message.value,
      botcheck: form.botcheck.value
    };
    var token = form.querySelector('[name="cf-turnstile-response"]');
    if (token && token.value) data["cf-turnstile-response"] = token.value;
    var body = JSON.stringify(data);
    fetch("https://formgong.com/submit", {
      method: "POST",
      headers: { "Content-Type": "application/json", Accept: "application/json" },
      body: body
    }).then(function (res) { return res.json(); }).then(function (result) {
      if (status) status.textContent = result && result.success ? (result.message || "Gesendet. Vielen Dank!") : ((result && result.message) || "Das Senden ist fehlgeschlagen. Bitte versuchen Sie es erneut.");
      if (result && result.success) form.reset();
    }).catch(function () {
      if (status) status.textContent = "Das Senden ist fehlgeschlagen. Bitte versuchen Sie es erneut.";
    });
  });
})();
</script>
Dasselbe Formular mit FormData statt JSON
Dasselbe Formular mit FormData statt JSON
<form id="fg-ajax" action="https://formgong.com/submit" method="POST" style="position:relative">
  <input type="hidden" name="access_key" value="fk_your_access_key">
  <input type="hidden" name="_lang" value="de">
  <label>Name <input type="text" name="name" autocomplete="name" required></label>
  <label>E-Mail <input type="email" name="email" autocomplete="email" required></label>
  <label>Telefon <input type="tel" name="phone" autocomplete="tel"></label>
  <label>Nachricht <textarea name="message" required></textarea></label>
  <div aria-hidden="true" style="position:absolute;inset-inline-start:0;top:0;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)">
  <label>Lassen Sie dieses Feld leer <input type="text" name="botcheck" tabindex="-1" autocomplete="off"></label>
</div>
  <!--
Optional. Schalten Sie Turnstile für dieses Formular ein, entfernen Sie diese Kommentarzeichen und fügen Sie den Site-Key ein.
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<div class="cf-turnstile" data-sitekey="YOUR_TURNSTILE_SITE_KEY" data-language="de"></div>
-->
  <button type="submit">Senden</button>
  <p data-status role="status"></p>
</form>
<script>
(function () {
  var form = document.getElementById("fg-ajax");
  if (!form) return;
  var status = form.querySelector("[data-status]");
  form.addEventListener("submit", function (event) {
    event.preventDefault();
    var body = new FormData(form);
    fetch("https://formgong.com/submit", {
      method: "POST",
      headers: { Accept: "application/json" },
      body: body
    }).then(function (res) { return res.json(); }).then(function (result) {
      if (status) status.textContent = result && result.success ? (result.message || "Gesendet. Vielen Dank!") : ((result && result.message) || "Das Senden ist fehlgeschlagen. Bitte versuchen Sie es erneut.");
      if (result && result.success) form.reset();
    }).catch(function () {
      if (status) status.textContent = "Das Senden ist fehlgeschlagen. Bitte versuchen Sie es erneut.";
    });
  });
})();
</script>

Fragen und Antworten

Warum hat das Formular noch eine Aktions-URL?

Damit das Absenden auch dann funktioniert, wenn JavaScript aus ist. Das Skript ruft preventDefault nur auf, wenn es tatsächlich läuft.

Soll ich JSON oder FormData senden?

Beides ist gültig. JSON nennt jedes Feld ausdrücklich. FormData ist kürzer, wenn Sie später Eingabefelder hinzufügen, weil es das Formular ausliest.

Die Statuszeile bleibt leer. Was ist fehlgeschlagen?

Prüfen Sie, dass Accept den Wert application/json hat, dass der Zugriffsschlüssel zu einem Formular gehört, das Sie besitzen, und dass die Seite über http oder https ausgeliefert wird, nicht als lokale Datei.

Kann dieses Formular eine Datei hochladen?

In dieser Vorlage nicht. Dateifelder brauchen eingeschaltete Anhänge und ein gültiges Turnstile-Token. Die Einrichtung dazu steht in der Dokumentation des Dashboards.