205 ist nicht, was du willst, siehe
205 im RFC 7231 zu HTTP/1.1.
Du hättest damit nicht die erwünschte Aktualisierung der Seite und damit kein Feedback für den Benutzer, weil der Standard eine Aktualisierung durch den Client nicht vorsieht und keine Nutzdaten gesendet werden dürfen, also nichts weiter als der Header selbst, und selbst für den gibt es Beschränkungen.
303 ist, was du suchst, siehe
303 im RFC 7231 zu HTTP/1.1 .
Hier ist das Laden der Ressource durch den Client Pflicht. 302 ist nur noch bei hoffnungslos veralteten Browsern sinnvoll. Da es aus Kompatibilitätsgründen entgegen dem Standard von den gängigen Browsern ähnlich wie 303 gehandhabt wird, funktioniert es trotzdem.
Dann müsstest du deinem Skript nur noch beibringen (praktischerweise das, welches die Post-Daten erhält), nichts weiter als den zu erstellenden Redirect-Header zu senden. Wie man in Python einzelne Headerzeilen überschreibt, müsstest du selbst sehen, da ich das nur in PHP kenne, wo es sehr einfach ist. In Python müsste das mit irgendeiner sperrigen Library gehen, ist ja im Gegensatz zu PHP nicht in erster Linie ein Homepage-Tool.
Prinzipiell kannst du Header aber auch selbst erzeugen (die letzte ist eine Leerzeile, sie ist Pflicht, bevor der erste Inhalt (z.B. HTML) kommt; wenn keiner kommt, sollte man sie weglassen; ob das CGI-Modul sie bei Bedarf automatisch einfügt, weiß ich nicht, weshalb sie vorsichtshalber da steht):
Code:
print("HTTP/1.1 303 See Other")
print("Location: http://meinehomepage.de/zielseite_der_umleitung")
print
# Hier könnte eine kleine HTML-Seite per print() mit einer Redirect-Meldung
ausgegeben werden, aber eigentlich braucht man das bei den heutigen
Geschwindigkeiten eher selten, weshalb ich mich auf den Header (ohne Leerzeile)
beschränken würde.
Die Zielseite gehört hier nicht hin, da der Browser wegen Status 303 das Get mit
der unter "Location: ..." angegebenen Ressource von sich aus veranlasst.
Was dein CGI-Modul daraus fabriziert, weiß ich nicht. Es sind ja noch einige andere Header üblich, vielleicht werden die automatisch eingefügt, könntest du mal ausprobieren, indem du sie im Browser anzeigen lässt, z.B. im Firefox mit der Erweiterung "Live HTTP headers". Insbesondere "Content-Length: 0" sowie "Connection: close" sind wichtig und dass es zu keinen Doppelungen kommt. Sollte es dazu kommen, ist vermutlich ein Kniff (oder eine Library) nötig, um das Überschreiben zu erzwingen. Oder man lässt einfach den Status-Header weg, falls der alleine doppelt ist und spekuliert darauf, dass das CGI-Modul den Redirect automatisch erkennt. Dann dürfte anstelle des 303 wegen Kompatibilität mir Uraltbrowsern eher ein 302 eingefügt werden, jedenfalls ist es bei PHP so, allerdings unter Verwendung von header().
Ist alles ein wenig mit Vorsicht zu genießen, weil ich mit Python-CGIs nicht vertraut bin, aber im Endeffekt sollten diese Headerzeilen produziert werden. In PHP gibt es dafür extra header(), was kaum Fragen aufwirft.
Vielleicht meldet sich hier noch jemand, der tiefer in der Materie drin steckt und die Fragen nach Ersetzung von Headern mit Python beantwortet. Sonst würde ich es einfach ausprobieren.
Habe in diesem Zusammenhang noch
dieses gefunden, vielleicht kann man damit einfach seine Response Header setzen, habe es aber nur überflogen. Sinngemäß müsste man der Funktion übergeben können, was sonst per print() ausgegeben würde, zzgl. evtl. weiterer Parameter.
Hier wird der allgemeine Vorgang zur Vermeidung von doppelten Posts anschaulich beschrieben:
http://en.wikipedia.org/wiki/Post/Redirect/Get
Solange der Browser den Status Code 303 einwandfrei implementiert, ist kein Doppelpost zu befürchten, falls ein Redirect auf die ursprüngliche Formularseite erfolgt (die dann ein Update erfahren hat), weil der Browser dann mit einem Get und nicht mit einem Post antwortet. Falls nichts veranlasst wird, sollte das Formular nach dem Laden der Seite wieder blank sein, wobei man die Rechnung ohne den Browser machen könnte, wenn der eine Autofill-Funktion aktiv hat.
Validieren würde ich die Formulare trotzdem, bevor sie weiterverarbeitet, gespeichert oder gar Mails aus ihnen gestrickt werden. Zudem würde ich wenigstens eine simple zufallsgenerierte Rechenaufgabe vorschalten, die von jedem leicht zu lösen ist, z.B. 2+3=_
Möglicherweise musst du mit Sessions arbeiten, um auf Benutzer individuell reagieren zu können. Aber es geht auch ohne, wenn es genügt, dass einfach auf eine vom Status abhängige Bestätigungsseite (Fehler vs. Erfolg) umgeleitet wird, von der aus man per Link entweder zum Formular oder zur Homepage zurückkehren kann. Das wäre schnell und würde den Server kaum belasten, hätte aber den Nachteil, dass der Nutzer nicht ganz auf den Kopf gefallen sein darf. Zwei eindeutige Links, evtl. als Pfeile, sollten hoffentlich noch verstanden werden. Wenn man immer denselben Navi-Bereich sieht, müsste es auch einfach so gehen, weshalb ich das mit der 205 schon nachvollziehen kann. Aber Feedback von JavaScript abhängig zu machen, ist nicht so gut.
Dann gibt es noch diesen alten Trick, den Browser beim Versenden der Formulardaten zu veranlassen, anstelle einer separaten Seite dieselbe Formularseite noch einmal aufzurufen, wobei man ihr die Daten übergibt, was dazu führt, dass sie im selben Skriptdurchlauf zur Verfügung stehen und ausgewertet werden, in dem auch das Formular erzeugt wird, was passende Fehlerausgaben bzw. Dynamisierung ohne Umleitung und ohne Sessions ermöglicht. Aber das löst dein Problem nicht, nur die Abwesenheit von Sessions, weil die Daten stets mitgesendet werden. Falls du so ein an sich selbst sendendes Formular hast: Mit einer 205 funktioniert das Prinzip nicht, weil keine Nutzdaten (PHP- bzw. Python-Datei) mitgesendet werden dürfen, s.o. Dann wäre aus Anwendersicht das Formular bloß im Browser zurückgesetzt und wieder kein Feedback vorhanden.
Wie man es auch dreht und wendet, man kommt mit 205 nicht weit, weil die angezeigte Seite zwar zurückgesetzte Eingabefelder hat, aber immer noch dieselbe ist, weshalb keine Abhängigkeit von den gesendeten Daten bestehen kann. Da bliebe vielleicht noch JavaScript im Browser übrig, um ein Feedback zu vermitteln, wenn man unbedingt 205 verwenden möchte. Aber das ist doof, weil das Skript beim Client zunächst nicht wissen kann, ob der Erfolg überhaupt eingetreten ist, sondern lediglich, ob die Eingaben plausibel waren. Man könnte damit den Server von einigen Berechnungen entlasten, aber ein echtes Feedback ist es eben nicht. Und wenn man das mit JavaScript haben will, stellt sich dasselbe Persistenzproblem wie sonst auch, wobei die Nachteile angesichts gestiegener Komplexität in Verbindung mit Timing noch viel größer ausfallen. Entweder bekommt der Nutzer ein Feedback oder keines, wobei echtes Feedback nur vom Server generiert werden kann. Alles andere ist Makulatur (bestenfalls Korrelation und ein rein grafischer Effekt), weil es keinen kausalen Zusammenhang gibt. Ein "Formular wurde gesendet", welches nicht lügt, möchte man als Benutzer gerne haben.