Absenden von HTML-Formularen

Absenden von HTML-Formularen6 Min. Lesezeit

Das action-Attribut von HTML-Formularen erklärt

Was das action-Attribut eines Formulars tut, wie relative und leere Werte aufgelöst werden, wie formaction ein Formular an zwei Ziele schickt und warum statische Hosts mit 405 antworten.

Preet SutharGründer, Ikiform

Das Attribut action ist die URL, an die ein Formular seine Daten sendet. Ein relativer Wert wird gegen die Adresse der Seite aufgelöst, ein leerer oder fehlender bedeutet die Seite selbst, und formaction an einem Submit-Button überschreibt ihn für diesen Button. Setze ihn auf einer statischen Site auf die vollständige URL eines Formular-Backends wie https://ikiform.com/f/<formId>, weil dein eigener Host den POST nicht annehmen kann.

Die meisten kaputten Formulare auf statischen Sites sind in genau diesem Attribut kaputt. Das Markup sieht gut aus, der Button funktioniert, und der Browser zeigt ein 405 oder eine leere Seite, weil die Daten irgendwohin gingen, wo sie nicht empfangen werden können. Diese Seite zeigt genau, wohin eine bestimmte action Daten sendet, und nutzt dann formaction, um ein Formular an zwei Posteingänge zu leiten.

Was hier anders ist

action ist eine URL wie jedes href, mit einer Besonderheit: Ein Formular ohne action tut nicht nichts, es sendet an die Seite, auf der es steht. Auf einer servergerenderten Site verarbeitet diese Seite den Post vielleicht. Auf einem statischen Host kann sie das nicht, also scheitert eine fehlende oder relative action erst nach dem Deploy.

Wohin jeder Wert die Daten sendet

Nimm eine Seite unter https://example.com/company/contact.html mit fünf Formularen darauf:

contact.html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<form action="/api/contact" method="post">
<form action="send" method="post">
<form action="" method="post">
<form method="post">
ActionWird aufgelöst zuAuf einem statischen Host
https://ikiform.com/f/frm_...Genau diese URLFunktioniert. Ikiform nimmt den POST an
/api/contacthttps://example.com/api/contactFunktioniert nur, wenn dein Host unter diesem Pfad eine Funktion ausführt
sendhttps://example.com/company/send, relativ zum Ordner405 oder 404
"" (empty)Die Seite selbst, contact.html405 auf den meisten statischen Hosts
FehltDie Seite selbst405 auf den meisten statischen Hosts
Wie der Browser aus dem action-Attribut eines Formulars die URL macht, an die er sendetabsolutrelativ, leer oder fehlendaction="https://ikiform.com/f/..."wie geschriebengenutztIkiform antwortetmit 303action="send" oderkeinegegen die Seiteaufgelöstoder ein <base href>,falls die Seite eineshatdein statischerHostkann kein POSTannehmen: 405Wie der Browser aus dem action-Attribut eines Formulars die URL macht, an die er sendetabsolutrelativ, leer oder fehlendaction="https://ikiform.com/f/..."wie geschrieben genutztIkiform antwortet mit 303action="send" oder keinegegen die Seite aufgelöstoder ein <base href>, falls dieSeite eines hatdein statischer Hostkann kein POST annehmen: 405
  1. Eine absolute action wird genau wie geschrieben genutzt, also erreicht der Post Ikiform, das mit einer Weiterleitung antwortet.
  2. Eine relative, leere oder fehlende action wird gegen die eigene Adresse der Seite aufgelöst oder gegen ein base-Element, falls die Seite eines hat.
  3. Der Post geht dann an deinen eigenen Host. Ein statischer Host liefert nur Dateien aus, lehnt den POST also ab, meist mit 405.
Zeigt die Adresszeile direkt nach dem Absenden deine eigene Domain, war die action relativ.
Ein <base href>-Element im Head der Seite ändert, wie jede relative URL aufgelöst wird, auch action. Manche Site-Builder und Single-Page-App-Setups fügen eines hinzu. Mit einer vollständigen URL spielt das keine Rolle.

Prüfen, was der Browser nutzen wird

In der Browserkonsole unterscheiden sich Attribut und Property. getAttribute gibt zurück, was du geschrieben hast; die Property action gibt die aufgelöste URL zurück, an die der Browser tatsächlich sendet:

Konsole
const form = document.querySelector("form");
form.getAttribute("action");
form.action;

Zeigt form.action deine eigene Domain, gehen die Daten dorthin. Builder wie Webflow und Framer setzen action oft aus ihrem eigenen Einstellungspanel, also prüfe die veröffentlichte Seite, nicht deinen Quelltext. Die Anleitungen für Site-Builder sagen, wo jeder Builder sie ablegt.

Ein Formular, zwei Posteingänge

formaction an einem Submit-Button ersetzt die action des Formulars nur für diesen Button. Hier gehen dieselben Felder an zwei Ikiform-Formulare. Ask support sendet an das Support-Formular, Talk to sales an das Vertriebsformular, und jedes Ikiform-Formular mailt an seine eigenen Empfänger:

contact.html
<form action="https://ikiform.com/f/frm_supportxxxxxxxxx" method="post">
  <label for="email">Email</label>
  <input id="email" name="email" type="email" autocomplete="email" required />

  <label for="message">How can we help?</label>
  <textarea id="message" name="message" rows="5" required></textarea>

  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Ask support</button>
  <button formaction="https://ikiform.com/f/frm_salesxxxxxxxxxxx">Talk to sales</button>
</form>
  • Jedes Ikiform-Formular hat eigene Benachrichtigungsempfänger, Spam-Einstellungen und Webhooks, sodass Support und Vertrieb nie die Post des anderen sehen.
  • Beide Formulare brauchen dieselbe Felddefinition oder keine. Mit definierten Feldern wird ein Feld, das ein Formular nicht kennt, mit 422 abgelehnt.
  • Die anderen form*-Attribute funktionieren genauso: formmethod, formenctype, formnovalidate und formtarget. Ein Button Save draft mit formnovalidate überspringt die Prüfungen des Browsers.
  • formaction funktioniert nur an Submit-Buttons: <button>, <input type="submit"> und <input type="image">.

Die Alternative ist ein Ikiform-Formular mit einem Feld topic und Weiterleitung nach Thema in einem Webhook oder deinen Posteingangsfiltern. So bleibt es bei einer Liste und einem Export. Zwei Formulare sind einfacher, wenn die beiden Teams überhaupt keine Empfänger teilen sollen.

action mit einem Query-String

Mit method="get" ersetzt der Browser den Query-String der action durch die Felder des Formulars. Das lang=de im ersten Formular unten fällt still weg; das zweite behält es als versteckten Input:

search.html
<form action="/search?lang=de" method="get">
  <input name="q" />
</form>

<form action="/search" method="get">
  <input name="q" />
  <input type="hidden" name="lang" value="de" />
</form>

Mit method="post" bleibt der Query-String erhalten, weil die Felder im Body stehen. Für Ikiform ändert das nichts: Query-Parameter an der Endpunkt-URL werden nicht gespeichert, also nutze versteckte Inputs für Werte, die erhalten bleiben sollen.

Inputs außerhalb des Formulars

Layouts brauchen manchmal einen Input, der nicht im <form>-Element steht, etwa eine Footer-Anmeldung neben anderem Inhalt. Das Attribut form an einem Input oder Button verbindet ihn über die id mit einem Formular, und er sendet an die action dieses Formulars:

footer.html
<form id="newsletter" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post"></form>

<footer>
  <input form="newsletter" name="email" type="email" required />
  <button form="newsletter">Subscribe</button>
</footer>

mailto:- und javascript:-Actions

action="mailto:you@example.com" bittet die Mail-App des Besuchers, eine Nachricht mit den Feldern zu öffnen. Es wird nichts gesendet, außer er hat eine Mail-App eingerichtet und drückt auf Senden, und du erfährst nie, dass er es versucht hat. action="javascript:..." führt Code aus, statt abzusenden, und wird von den meisten Content Security Policies blockiert. Beides solltest du durch einen echten Endpunkt ersetzen.

Prüfen, ob es funktioniert

  1. Füge unter Allowed domains des Formulars die Domain deiner Site hinzu, plus localhost, während du entwickelst. Lass das Feld leer, um Posts von überall anzunehmen.
  2. Öffne die veröffentlichte Seite, nicht deinen Quelltext, und führe document.querySelector("form").action in der Konsole aus. Es gibt deine vollständige Ikiform-URL aus.
  3. Sende das Formular ab. Das Network-Panel zeigt einen POST an ikiform.com, beantwortet mit 303, keinen POST an deine eigene Domain.
  4. Sende im Formular mit zwei Posteingängen einmal mit jedem Button ab. Jede Einsendung erscheint im Dashboard unter ihrem eigenen Formular.
  5. Prüfe das Postfach jedes Benachrichtigungsempfängers. Jeder bekommt eine E-Mail mit den Feldern, und Reply geht an den Absender, wenn das Formular ein email-Feld hat.

Stolperfallen

ProblemUrsache und Lösung
405 Method Not Allowed von deiner eigenen DomainDie action ist relativ, leer oder fehlt, also ging der Post an deinen statischen Host. Nutze die vollständige Ikiform-URL
404 not_found von ikiform.comDie Formular-ID in der action ist falsch, oder das Formular wurde gelöscht. Kopiere den Endpunkt von der Seite des Formulars im Dashboard
Der Builder setzt die action immer wieder zurückManche Builder kontrollieren die action ihres Formularblocks. Nutze ihre Einstellung für eine eigene Action oder ein Embed mit deinem eigenen Markup
Der Browser warnt, dass das Formular nicht sicher istDie action nutzt http: auf einer https:-Seite. Ikiforms Endpunkt ist nur https:; korrigiere das Schema
Felder aus einem zweiten Formular werden mitgesendetFormulare lassen sich nicht verschachteln. Der Browser schließt das äußere Formular am inneren <form>-Tag. Nutze stattdessen das Attribut form

Den vollständigen Ablauf vom Klick bis zur Weiterleitung findest du in der Übersicht. Alles, was der Endpunkt annimmt, steht in HTML-Formulare.

Fragen

Hängst du bei einem Schritt fest oder willst eine Anleitung für deinen Fall? Schreib an hello@ikiform.com.