Widzieliście ostrzeżenia typu „nie odświeżaj strony, ani nie używaj przycisku wstecz przeglądarki” ? Zapewne tak, bo to dość często stosowana praktyka zapobiegania ponownemu wysłaniu danych np. poprzez formularz. Praktyka powszechna, ale metoda rozwiązania problemu żadna.

Weźmy przykład – formularz przelewu internetowego. Wypełniamy dane, klikamy przycisk Akceptuj. Dane o transakcji zostają wysłane do serwera za pomocą metody POST. Serwer odnotowuje zmiany w bazie danych. Załadowana zostaje ta sama strona z formularzem. Użytkownik klika wstecz. Przeglądarka z reguły rzuca ostrzeżeniem o powtórnym przesłaniu danych żądaniem POST. Wiadomość jest zbyt konfundująca, użytkownik nieopatrznie zgadza się na ponowne przesłanie danych. Pieniądze zostają przelane dwukrotnie.

Co zrobić by uniknąć pozwów od użytkowników takich jak powyżej? Ostrzec, że za ich działania na stronie nie odpowiadamy prawnie lub użyć przekierowania po przetworzeniu danych otrzymanych POST-em. Tylko tyle i aż tyle. Teraz przykład wypisania z listy mailingowej. Schemat działania zawarty w trzech plikach:

form.html z prostym formularzem:


<form action="form_post.php" method="post">
   <input type="text" name="email" />
   <input type="submit" value="Wyślij" />
</form>

form_post.php przetwarzający dane (operacje na bazie danych itp.)


<?php
if(isset($_POST['email'])){
   // usuń e-mail z bazy subskrybentów
}
//przekierowanie z parametrem - adresem e-mail (metoda GET!)
header('Location: form_result.php?email=' . $_POST['email']);
?>

form_result.php, czyli plik wynikowy z rezultatem operacji


<?php
if(isset($_GET['email'])){
   //pobierz dane np. imię i nazwisko z bazy danych
   $query = "SELECT name, surname FORM users WHERE email = ?";
   //podstawienie $_GET['email'] pod zmienną wiązania i zwrócenie wyniku bazy danych
   (...)
   echo "$name $surname, zostałeś poprawnie wypisany z newslettera.";
}
?>

Voila! Teraz nawet po naciśnięciu przycisku wstecz, nie ma zagrożenia, ponieważ strona rezultatu operacji była ładowana za pomocą metody GET.

Idea szerzej opisana w artykule Redirect After Post.