Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Blokowanie wysyłania podwójnego formularza.
Forum PHP.pl > Forum > Przedszkole
Jediii
Witam.

Nie mogę sobie poradzić z blokowanie wysyłania podwójnego formularza i odświeżania strony. Mam nadzieję, że uzyskam od Was jakie wskazówki, jak poradzić sobie z tym problemem.

Mam formularz w pliku form.php. Jego wysłanie zostaje przetworzone w tym samym pliku i gdy zostaną wykonane odpowiednio zapytania do bazy (załóżmy, że walidacja przeszła ok) pojawi się komunikat, ze zostało coś dodane oraz będzie możliwość, ponownie przez ten formularz (form.php), dodania kolejne rzeczy. Nie jest tutaj stosowane żadne przekierowanie.

Nie mam pojęcia, jak zablokować to podwójne wysyłanie formularza. Trochę kombinowałem z sesjami, jednak bez rezultatów.

Dodam jeszcze, że dodane w bazie informacje w bazie przez ten formularz mogą się powtarzać, więc rozwiązanie sprawdzenie, czy w bazie coś już takiego istnieje odpada.

Będę wdzięczny za każdą pomocą.





b4rt3kk
Przekierowanie do strony np. success.php gdzie tylko pisze, że poprawnie dodano czy coś tam i z tej strony kolejne przekierowanie, z powrotem do formularza.
bostaf
Z pomocą przyjdzie Ci jeden z podstawowych wzorców projektowych w programowaniu aplikacji webowych, a mianowicie PRG czyli post/redirect/get. Możesz poczytać o tym trochę na wikipedii: Post/Redirect/Get (niestety tylko po angielsku), albo pogooglować (taki mini artykulik znalazłem: Wielki Post i mały Get.

Generalnie chodzi o to, żeby najpierw sprawdzić, czy jakieś dane są przesyłane POSTem a dopiero potem zadecydować co robić dalej. Dla przykładu, w jednym skrypcie:

  1. <?php
  2. if(isset($_POST['dane']))
  3. {
  4. // filtruję, waliduję, obrabiam, wysyłam do bazy, itp.
  5. // zapisuję w sesji informację, że wszystko OK, albo że nie OK:
  6. if($wszystko_ok)
  7. {
  8. $_SESSION['komunikat'] = 'Dane zapisane! :)';
  9. } else {
  10. $_SESSION['komunikat'] = 'Coś się nie udało :(';
  11. }
  12. // na koniec przekierowuję skrypt:
  13. header('Location: ' . $_SERVER['REQUEST_URI']);
  14. // po przeładowaniu dane POST już nie będą istniały, więc skrypt pominie całą tą klamrę i przejdzie dalej
  15. }
  16. ?>
  17. <div class="komunikat">
  18. <?php
  19. if(isset($_SESSION['komunikat'])) :
  20. echo $_SESSION['komunikat'];
  21. unset($_SESSION['komunikat']); // usuwam komunikat z sesji, żeby za każdym razem się nie wyświtlał
  22. endif;
  23. ?>
  24. </div>
  25. <form action="<?php echo $_SERVER['REQUEST_URI'];?>" method="post">
  26. <input type="text" name="dane">
  27. <input type="submit">
  28. </form>
Jediii
Dziękuję Wam za odpowiedzi. Będę kombinować dalej i zobaczymy, co z tego wyjdzie. W razie jakiś pytań, pewnie się tutaj odezwę. smile.gif
Krychu1
Tak, wiem że kopię... smile.gif Robię to jednak dlatego, że ten wątek pojawia się dosyć wysoko w google, a udzielona odpowiedź nie do końca rozwiązuje problem.
Wpadłem właśnie na pomysł, bardzo prosty pomysł.
Podczas wysyłania formularza, wysyłamy także dodatkowy ukryty input, który przechowuje wartość wygenerowaną przez funkcję rand() - czyli krótko mówiąc jakąś liczbę z przedziału dziesiątek tysięcy. Szansa więc na powtórzenie się tej samej wynosi 1 do kilkudziesięciu tysięcy. Pobraną wartość rand() z formularza zapisujemy w sesji i przed wykonaniem np. zapytania do bazy (bo to jest z reguły największym problemem) sprawdzamy czy nowa sesja jest identyczna z tą, która zapisaliśmy wcześniej. Jeśli tak, oznacza to że użytkownik odświeżył stronę, a my zablokujemy mu możliwość ponownego wykonania kodu (w tym wypadku zapytania do bazy).

  1. <?php
  2. if(isset($_POST['submit'])){
  3. if(!isset($_SESSION['sesja']) || (isset($_SESSION['sesja']) && $_SESSION['sesja'] != $_POST['sesja'])){
  4. $_SESSION['sesja'] = $_POST['sesja'];
  5.  
  6. //zapytanie do bazy
  7. }
  8. else
  9. echo 'Odświeżyłeś stronę';
  10. }
  11.  
  12. echo '<form action="" method="POST">
  13. <input type="hidden" name="sesja" value="'.rand().'" />
  14. <input type="submit" name="submit" value="Wyślij" />
  15. </form>';
  16. ?>


Wpadłem na to jak widać o 1:51. Pomysł może być kulawy, jednak na tę chwilę wydaje mi się, że wszystko działa jak należy. Jeśli ktoś bardziej zaawansowany na to spojrzy, fajnie gdyby stwierdził czy to rzeczywiście jest takim świetnym rozwiązaniem.

@EDIT
Przeglądając dalej google z ciekawości, czy ten sposób jest rzeczywiście wystarczający dowiedziałem się że to co przedstawiłem potocznie nazywa się tokenem - a to wcale nic nowego. smile.gif W każdym razie tak jak napisałem na początku. Po wpisaniu hasła "blokada podwójnego wysłania formularza" w google, temat ten jest na pierwszym miejscu, a więc warto było podbić wątek.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.