Ich ergänz mal ein bisschen
Das Problem tritt natürlich häufig auf, aber im Sinne eines REST-vollen Designs sind beide Lösungen suboptimal, wirklich sauber wäre es wohl, wenn die Meldung dass alles OK übertragen wurde, unter einem ganz anderen URL erscheinen würde. Dafür gibt es HTTP-Redirects, zum Beispiel folgendes Design:
- GET-Request nach /admin/products/foo: Bearbeiten-Formular
- POST-Request nach /admin/products/foo: Aktualisieren; bei Misserfolg erneutes Anzeigen des Formulars mit Fehlermeldungen. Bei Erfolg: Redirect nach /admin/message, wo einem gesagt wird, dass alles OK ist
Welche Nachricht da jetzt genau angezeigt wird, wird per Session gespeichert, dafür haben viele moderne Web-Frameworks eine oft so genannte "flash"-Methode. Durch die Umleitung gibt es kein Problem mit erneuter Absendung gültiger Daten per Reload-Knopp, man ist ja bei 'nem ganz anderen URL. OK, möglicherweise ist dann die Meldung weg, aber die Daten gehen nicht kaputt.
Gegen eine Lösung mit verzögertem Refresh spricht, dass während dieser Verzögerung per Reload trotzdem Mist gemacht werden kann. Außerdem hat das W3C noch ein paar
gute Argumente gegen Refreshs.
Das mit der vergebenen ID ist natürlich trickreich, aber man hat immer noch keine schönen getrennten URLs fürs Absenden und die Meldung.
Ich habe mal ein kleines Beispielskript vorbereitet, was den Mechanismus ganz anschaulich macht:
Hier aber mal das wesentliche (die Routes sind im Gist ab Zeile 9): ein GET-Request auf /edit zeigt einfach das Ändern-Formular an, im Template wird noch der eventuell bekannte Name aus der Session geholt (siehe unten im Skript). Ein Post-Request auf /edit ändert den Namen in der Session auf den per Formular übermittelten. Anschließend wird eine Nachricht in die Session eingetragen und zur Nachricht-Anzeige-Seite weitergeleitet. Was da rauskommt, ist ein handelsüblicher 302-Redirect, also ein "temporärer", das ist genau das richtige für unsere Zwecke. Die einzige "komplexe" Aktion da ist das update auf POST /edit, die anderen Actions zeigen nur Daten an, deshalb findet da alles nur in den Templates unten im Skript statt.
HTH und viele Grüße
Mirko