Πως να αποφύγετε τα refresh των forms

Σε αυτή την περιοχή μπορείτε να βρείτε ή να αναζητήσετε πληροφορίες σχετικές με την PHP

Συντονιστές: WebDev Moderators, Super-Moderators

Απάντηση
Άβαταρ μέλους
cpulse
Script Master
Δημοσιεύσεις: 1527
Εγγραφή: 21 Μαρ 2006 19:30
Τοποθεσία: Αθήνα village
Επικοινωνία:

Πως να αποφύγετε τα refresh των forms

Δημοσίευση από cpulse » 24 Σεπ 2006 15:01

Φαντάζομαι θα υπάρχουν διάφοροι τρόποι για να αποφεύγετε τις διπλοεγγραφές στα forms. Θα σας πω πως το αντιμετωπίζω εγώ. Η μέθοδος που χρησιμοποιώ χρειάζεται sessions.

Η ιδέα είναι απλή: Κάθε form έχει ένα μοναδικό χαρακτηριστικό και το σύστημα όταν αντιλαμβάνεται οτι αυτό επαναλαμβάνεται συμπεραίνει οτι έχει γίνει refresh. Για να το καταφέρω αυτό βάζω σε κάθε form ένα hidden field που πάντα το ονομάζω hfrm. Βολεύει για μοναδική τιμή η χρήση του microtime().

Κώδικας: Επιλογή όλων

<input type="hidden" name="hfrm" value="<?php echo microtime&#40;&#41;; ?>">
Πριν από την επεξεργασία του form πρέπει να δούμε αν το προηγούμενο hfrm είναι το ίδιο με το παλιό και να αποθηκεύσουμε τις τρέχουσες τιμές:

Κώδικας: Επιλογή όλων

$hfrm = isset&#40;$_POST&#91;'hfrm'&#93;&#41; ? $_POST&#91;'hfrm'&#93; &#58; '';
$pageRefreshed = $hfrm != '' && $hfrm == $_SESSION&#91;'last_hfrm'&#93;;
$_SESSION&#91;'last_hfrm'&#93; = $hfrm;
Τώρα με ασφάλεια μπορούμε να κάνουμε ελεγχόμενες αλλαγές:

Κώδικας: Επιλογή όλων

if &#40;isset&#40;$_POST&#91;'hfrm'&#93;&#41; && !$pageRefreshed&#41; &#123;
  .. προσθέσεις, αφαιρέσεις, αλλαγές τιμών
&#125;
Όλα αυτά αντιμετωπίζουν την περίπτωση του refresh, αλλά τι γίνεται αν ο χρήστης πατήσει το back και μετά forward; Η λύση σε αυτό είναι εύκολη, να πούμε στον browser να μην κάνει cache. Οπότε βάζουμε στον html header:

Κώδικας: Επιλογή όλων

<meta http-equiv="Pragma" content="no-cache" />

Άβαταρ μέλους
cherouvim
Script Master
Δημοσιεύσεις: 3137
Εγγραφή: 13 Ιούλ 2005 22:56
Τοποθεσία: Athens, Greece
Επικοινωνία:

Πως να αποφύγετε τα refresh των forms

Δημοσίευση από cherouvim » 24 Σεπ 2006 15:34

Ώραίο! Ένας άλλος τρόπος είναι σε κάθε form rendering να φυτεύεις ένα token (random number ας πούμε) το οποίο έχεις ήδη αποθηκεύσει στο session. Form submissions που λαμβάνεις υπόψιν θα πρέπει να έχουν hidden value τι τιμή αυτού του token. Έτσι δεν έχεις πρόβλημα και με το back/resubmit, γιατί το token θα έχει ήδη καταναλωθεί την πρώτη φορά.

Άβαταρ μέλους
greekbytes
WebDev Moderator
Δημοσιεύσεις: 2438
Εγγραφή: 15 Νοέμ 2002 15:42
Τοποθεσία: Αθήνα
Επικοινωνία:

Πως να αποφύγετε τα refresh των forms

Δημοσίευση από greekbytes » 24 Σεπ 2006 16:12

Πολύ καλό! Έγινε βοήθημα!

Αν έχετε όρεξη μπορεί κάποιος από τους δύο να αναπτύξει και ένα παράδειγμα με τον τρόπο που αναφέρει ο cherouvim για να είναι ακόμα πιο ολοκληρωμένο το tut.. ;)

Άβαταρ μέλους
cpulse
Script Master
Δημοσιεύσεις: 1527
Εγγραφή: 21 Μαρ 2006 19:30
Τοποθεσία: Αθήνα village
Επικοινωνία:

Πως να αποφύγετε τα refresh των forms

Δημοσίευση από cpulse » 24 Σεπ 2006 16:57

Σας ευχαριστώ για τα καλά σας λόγια.

Νομίζω κατάλαβα τι λέει ο cherouvim αλλά αυτό θα δημιουργούσε ένα array με άχρηστα tokens. Ο τρόπος σκέψης του πάντως είναι πολύ χρήσιμος στην περίπτωση που τα δεδομένα μπαίνουν με κάρτες, δηλαδή με πολλές σελίδες από forms. Πχ.. σε ένα ερωτηματολόγιο που οι ερωτήσεις είναι μοιρασμένες σε σελίδες για να μην κουράζουν τον χρήστη. Εκεί χρειάζεται το token για να καταλαβαίνει το σύστημα σε πια κάρτα βρίσκεται ο χρήστης. Έτσι μπορεί να κάνει τα σωστά validations και να ξέρει ποια είναι η προηγούμενη και η επόμενη κάρτα.

Ενα πλήρες παράδειγμα για τον τρόπο που ανέφερα στην αρχή:

Κώδικας: Επιλογή όλων

<?php

  session_start&#40;&#41;;

  if &#40;!isset&#40;$_SESSION&#91;'last_hfrm'&#93;&#41;&#41; $_SESSION&#91;'last_hfrm'&#93; = '';

  $hfrm = isset&#40;$_POST&#91;'hfrm'&#93;&#41; ? $_POST&#91;'hfrm'&#93; &#58; '';
  $pageRefreshed = $hfrm != '' && $hfrm == $_SESSION&#91;'last_hfrm'&#93;;
  $_SESSION&#91;'last_hfrm'&#93; = $hfrm;

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
	"http&#58;//www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Ελεγχόμενο POST</title>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7" />
</head>
<body>

<?php
  if &#40;isset&#40;$_POST&#91;'hfrm'&#93;&#41;&#41; &#123;
    if &#40;!$pageRefreshed&#41; &#123;
      .. προσθέσεις, αφαιρέσεις, αλλαγές τιμών 
    &#125;
?>

<p>Το κείμενο καταχωρήθηκε επιτυχώς</p>

<?php
  &#125; else &#123;
?>

<form name="frm" method="post" action="<?php echo $_SERVER&#91;'PHP_SELF'&#93;; ?>">
  <input type="hidden" name="hfrm" value="<?php echo microtime&#40;&#41;; ?>">
  Κείμενο&#58; <input type="text" name="txtKeimeno" value="">
  <input type="submit" name="btnSubmit" value="Αποστολή">
</form>

<?php
  &#125;
?>

</body>
</html>

Άβαταρ μέλους
cherouvim
Script Master
Δημοσιεύσεις: 3137
Εγγραφή: 13 Ιούλ 2005 22:56
Τοποθεσία: Athens, Greece
Επικοινωνία:

Πως να αποφύγετε τα refresh των forms

Δημοσίευση από cherouvim » 24 Σεπ 2006 17:21

Δεν χρειάζεται array. Απλά η αποθήκευση του τελευταίου token στο session.

Κώδικας: Επιλογή όλων

<?
session_start&#40;&#41;;

if &#40;isset&#40;$_POST&#91;'submit'&#93;&#41;&#41; &#123;
	if &#40;isset&#40;$_SESSION&#91;'token'&#93;&#41; &&
		$_POST&#91;'token'&#93;==$_SESSION&#91;'token'&#93;&#41; &#123;
		
		//process form
		...
		//reset token
		$_SESSION&#91;'token'&#93; = null;
		
	&#125; else &#123;
		echo "double submit";
	&#125;
&#125;

$_SESSION&#91;"token"&#93;=rand&#40;&#41;;

?>
<form action="?" method="post"><input type="hidden" name="token" value="<?=$_SESSION&#91;"token"&#93;?>" />
  <input type="text" name="foo1" /><br/>
  <input type="text" name="foo2" /><br/>
  <input type="text" name="foo3" /><br/>
  <input type="submit" name="submit" />
</form>

Απάντηση

Επιστροφή στο “PHP Προγραμματισμός”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες