Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL][PHP]Blokowanie wysyłania podwójnego formularza.
Jediii
post 6.10.2012, 11:44:07
Post #1





Grupa: Zarejestrowani
Postów: 12
Pomógł: 0
Dołączył: 21.09.2011

Ostrzeżenie: (0%)
-----


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ą.





Go to the top of the page
+Quote Post
b4rt3kk
post 6.10.2012, 11:58:59
Post #2





Grupa: Zarejestrowani
Postów: 1 933
Pomógł: 460
Dołączył: 2.04.2010
Skąd: Lublin

Ostrzeżenie: (0%)
-----


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.


--------------------
Jeśli pomogłem, kliknij proszę 'pomógł'. Dzięki.
Go to the top of the page
+Quote Post
bostaf
post 6.10.2012, 12:41:39
Post #3





Grupa: Zarejestrowani
Postów: 374
Pomógł: 79
Dołączył: 6.04.2010
Skąd: Ostrów Wielkopolski

Ostrzeżenie: (0%)
-----


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>
Go to the top of the page
+Quote Post
Jediii
post 6.10.2012, 15:51:10
Post #4





Grupa: Zarejestrowani
Postów: 12
Pomógł: 0
Dołączył: 21.09.2011

Ostrzeżenie: (0%)
-----


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
Go to the top of the page
+Quote Post
Krychu1
post 16.08.2013, 00:54:10
Post #5





Grupa: Zarejestrowani
Postów: 39
Pomógł: 1
Dołączył: 3.10.2009

Ostrzeżenie: (0%)
-----


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.

Ten post edytował Krychu1 16.08.2013, 01:16:11
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 5.06.2025 - 20:27