webentwicklung-frage-antwort-db.com.de

Erneutes Senden von Formularen verhindern, wenn die Schaltfläche "Zurück" gedrückt wird

Ich habe viele Beiträge hier und anderswo gesucht, kann aber anscheinend keine Lösung für mein Problem finden. Ich habe eine Seite, die Datenbankeinträge anzeigt: database.php. Diese Einträge können mit einem Formular gefiltert werden. Wenn ich sie filtern und nur die anzeigen kann, für die ich mich interessiere, kann ich auf einen Eintrag (als Link) klicken, der mich zu dieser Eintragsseite (über PHP GET) führt. Wenn ich mich auf dieser Eintragsseite befinde (d. H. "View.php? Id = 1") und auf die Zurück-Schaltfläche (zurück zur Datenbank.php) klicke, muss das Filterformular die erneute Vorlage des Formulars bestätigen. Gibt es eine Möglichkeit, dies zu verhindern?

hier einige (vereinfachte) Codebeispiele:

Database.php:

<form>
    <select>
        <option>1</option>
        <option>2
        <option>
    </select>
    <input type="submit" name="apply_filter" />
</form>
<?php
if ( isset( $_POST[ "apply_filter" ] ) ) { // display filtered entries
    $filter = $_POST[ "filter" ];
    $q = "Select * from table where col = '" . $filter . "'";
    $r = mysql_query( $q );
} else { // display all entries
    $q = "Select * from table";
    $r = mysql_query( $q );
}
while ( $rec = mysql_fetch_assoc( $r ) ) {
    echo "<a href='view.php?id=" . $rec[ "id" ] . "'>" . $rec[ "name" ] . "</a><br />"; // this is where the link to the view.php page is...
}
?>

Wenn ich jetzt auf den Link klicke, dann komme ich zu "view.php? Id = wie auch immer". Auf dieser Seite erhalte ich nur die ID von der URL, um diesen einzelnen Eintrag anzuzeigen:

view.php:

<?php
$id = $_GET[ "id" ];
$q = "Select * from table where id = '" . $id . "'";
$r = mysql_query( $q );
while (  ) {
    // display entry
}

?>

Wenn ich jetzt auf die Schaltfläche "Zurück" klicke, muss das Formular in database.php (das zum Filtern der DB-Ergebnisse verwendet wird) zur erneuten Übermittlung bestätigt werden. Dies ist nicht nur sehr ärgerlich, sondern auch für mich nutzlos.

Wie kann ich das beheben? Ich hoffe, die Codebeispiele und die Erklärung meines Problems sind ausreichend. Wenn nicht, lass es mich wissen und ich versuche es zu spezifizieren.

20
user1889382

Ich weiß, dass diese Frage alt ist, aber da ich diese Ausgabe selbst habe, habe ich zwei Zeilen entdeckt, die folgende Werke haben:

header("Cache-Control: no cache");
session_cache_limiter("private_no_expire");
23

Ich kenne zwei Möglichkeiten, dies zu tun. Der einfache Weg und der harte Weg.

Unabhängig von der Art und Weise, wenn Sie es mit einer zustandsbasierten Seite (mit $_SESSION) zu tun haben, die Sie tun sollten, um Ihre Seiten "live" zu halten und unter Ihrer Kontrolle zu halten, verhindern Sie das Zwischenspeichern aller Seiten wie folgt:

<?php
//Set no caching
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
header("Cache-Control: no-store, no-cache, must-revalidate"); 
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>

Die harte Tour besteht darin, eine ID zu generieren und irgendwo auf der Seite als versteckte Eingabe oder als &_SESSION-Cookie zu speichern. Dann speichern Sie dieselbe ID als $_SESSION auf dem Server. Wenn sie nicht übereinstimmen, führt eine Reihe von vorprogrammierten Anweisungen vom Typ ifelse dazu, dass nichts passiert, wenn die Seite erneut übermittelt wird (dies ist die Aufgabe, die beim Zurückklicken ausgeführt wird).

Der einfache Weg besteht darin, den Benutzer einfach zurück auf die Formularübermittlungsseite umzuleiten, wenn das Formular erfolgreich gesendet wurde.

header('Location: http://www.mydomain.com/redirect.php');

Ich hoffe das hilft!

8
Phillip Berger

Eine Sache, die helfen könnte, ist, dass Ihr Filterformular anstelle von GET eine POST-Methode verwendet.

Browser verhindern normalerweise, dass die Eingabe von POST automatisch erneut übermittelt wird, was sie nicht tun, wenn die Eingabe GET verwendet wird. Außerdem können Benutzer mithilfe eines Filters auf Ihre Seite zugreifen.

3
tanios

Eine alternative Lösung, die auch funktioniert, wenn/wenn die Seite neu geladen wird, beinhaltet die Überprüfung der Originalität des Beitrags mit $ _SESSION. Suchen Sie in aller Kürze nach einer eindeutigen oder zufälligen Zeichenfolge.

Fügen Sie im Formular ein Eingabeelement mit einem mit Rand () oder microtime () festgelegten Wert hinzu:

<input type="hidden" name="formToken" value="<?php echo microtime();?>"/>

Umschließen Sie dann die Funktion PHP, um die Formulardaten in einem if-Block zu überprüfen und zu analysieren:

if(!isset($_SESSION['formToken']) || $_POST['formToken'] !== $_SESSION['formToken'])){
       $_SESSION['formToken'] = $_POST['formToken'];
      /*continue form processing */
}
0
SilentStone

Ich habe die Antwort bei verwendet. Wie erkenne ich, ob ein Benutzer mithilfe der Zurück-Taste auf eine Seite gelangt ist? um zu erkennen, ob der Besuch durch das Klicken mit der hinteren Schaltfläche eines Browsers ausgelöst wurde oder nicht, und wenn dies der Fall war, verwendete ich JavaScript zum Neuladen der Seite. Wenn die Seite neu geladen wird, verarbeitet mein Code bereits die entsprechenden Überprüfungen, um sicherzustellen, dass das Formular niemals zweimal gesendet wird. In meinem Fall war es wichtig, das erneute Laden der Seite zu erzwingen, wenn das Formular nach dem Klicken auf die Zurück-Schaltfläche des Browsers erneut aufgerufen wurde. Dies ist mein Code in der URL, auf den ich diese Überprüfung anwenden wollte:

<script type="text/javascript">
    if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
        location.reload();
    }
</script>
0
Jaime Montoya

header ("Cache-Control: kein Cache");

session_cache_limiter ("private_no_expire");

HINWEIS: Nachdem Sie die von Ihnen übermittelten Post-Daten verwendet haben, sollten diese beiden Zeilen am Ende der Funktion verwendet werden. Wenn wir also zur umgeleiteten Seite zurückkehren, werden Sie nicht aufgefordert, die Seite erneut zu übermitteln. Das wird funktionieren.

0