webentwicklung-frage-antwort-db.com.de

Am besten vermeiden Sie das Senden aufgrund einer Aktualisierung der Seite

Ich denke, dass dieses Problem häufig bei der Entwicklung von Webanwendungen auftritt. Aber ich werde versuchen, mein Problem ausführlich zu erklären. 

Ich würde gerne wissen, wie man dieses Verhalten korrigiert, zum Beispiel, wenn ich einen Codeblock wie diesen habe:

<?
    if (isset($_POST['name'])) {
        ... operation on database, like to insert $_POST['name'] in a table ...
        echo "Operation Done";
        die();
    }

?>

<form action='page.php' method='post' name="myForm">
    <input type="text" maxlength="50" name="name" class="input400" />
    <input type="submit" name="Submit" />
</form>

Wenn das Formular gesendet wird, werden die Daten in die Datenbank eingefügt und die Nachricht Operation Done wird erstellt. Wenn ich die Seite aktualisiert habe, würden die Daten dann erneut in die Datenbank eingefügt.

Wie kann dieses Problem vermieden werden? Jeder Vorschlag wird geschätzt :)

21
markzzz

Zeigen Sie die Antwort nach Ihrer Erstellungsaktion nicht an. Stattdessen auf eine andere Seite umleiten, nachdem die Aktion abgeschlossen ist. Wenn jemand aktualisiert wird, wird die von GET angeforderte Seite aktualisiert, zu der Sie weitergeleitet wurden.

// submit
// set success flash message (you are using a framework, right?)
header('Location: /path/to/record');
exit;
34
coreyward

Legen Sie eine zufällige Nummer in einer Sitzung fest, wenn das Formular angezeigt wird, und geben Sie diese Nummer in ein ausgeblendetes Feld ein. Wenn die gebuchte Nummer und die Sitzungsnummer übereinstimmen, löschen Sie die Sitzung und führen Sie die Abfrage aus. Wenn dies nicht der Fall ist, zeigen Sie das Formular erneut an und generieren Sie eine neue Sitzungsnummer. Dies ist die Grundidee von XSRF-Token. Sie können mehr über sie und ihre Verwendung zur Sicherheit hier lesen: http://en.wikipedia.org/wiki/Cross-site_request_forgery

Hier ist ein Beispiel:

<?php
session_start();

if (isset($_POST['formid']) && isset($_SESSION['formid']) && $_POST["formid"] == $_SESSION["formid"])
{
    $_SESSION["formid"] = '';
    echo 'Process form';
}
else
{
    $_SESSION["formid"] = md5(Rand(0,10000000));
?>
    <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
    <input type="hidden" name="formid" value="<?php echo htmlspecialchars($_SESSION["formid"]); ?>" />
    <input type="submit" name="submit" />
</form>
<?php } ?>
25
Ben

So was:

<?php
if(isset($_POST['uniqid']) AND $_POST['uniqid'] == $_SESSION['uniqid']){
    // can't submit again
}
else{
    // submit!
    $_SESSION['uniqid'] = $_POST['uniqid'];
}
?>

<form action="page.php" method="post" name="myForm">
    <input type="hidden" name="uniqid" value="<?php echo uniqid();?>" />
    <!-- the rest of the fields here -->
</form>

Ich denke es ist einfacher,

page.php

<?php
   session_start();
   if (isset($_POST['name'])) {
        ... operation on database, like to insert $_POST['name'] in a table ...
        $_SESSION["message"]="Operation Done";
        header("Location:page.php");
        exit;
    }
?>

<html>
<body>
<div style='some styles'>
<?php
//message here
echo $_SESSION["message"];
?>
</div>
<form action='page.php' method='post'>
<!--elements-->
</form>
</body>
</html>
1
Sherin Jose

Keine Notwendigkeit, umzuleiten ...

ersetzen Sie die(); durch 

isset(! $_POST['name']);

Wenn Sie das Isset auf $ _POST ['Name'] setzen, wird es bei der Aktualisierung nicht mehr zu Ihrer Datenbank hinzugefügt, es sei denn, Sie klicken erneut auf die Schaltfläche "Senden".

<?
    if (isset($_POST['name'])) {
        ... operation on database, like to insert $_POST['name'] in a table ...
        echo "Operation Done";
        isset(! $_POST['name']);
    }

?>

<form action='page.php' method='post' name="myForm">
    <input type="text" maxlength="50" name="name" class="input400" />
    <input type="submit" name="Submit" />
</form>
1
Guest

Ich bin auf ein ähnliches Problem gestoßen. Ich muss dem Benutzer das Ergebnis des POST anzeigen. Ich möchte keine Sitzungen verwenden und ich möchte nicht mit dem Ergebnis in der URL umleiten (es ist irgendwie sicher, ich möchte nicht, dass es versehentlich mit einem Lesezeichen versehen wird). Ich habe eine ziemlich einfache Lösung gefunden, die für die in anderen Antworten genannten Fälle funktionieren sollte.

Fügen Sie nach dem erfolgreichen Senden des Formulars dieses Javascript hinzu:

<script>history.pushState({}, "", "")</script>

Die aktuelle URL wird auf den Protokollstapel verschoben. Da dies ein neues Element in der Historie ist, wird die Aktualisierung nicht erneut durchgeführt.

0
Cully

Also, was ich brauchte, ist das, was funktioniert.

Basierend auf all den oben genannten Lösungen kann ich von einem Formular zu einem anderen Formular und zu dem Formular n ^ wechseln, während gleichzeitig verhindert wird, dass dieselben exakten Daten immer wieder "gespeichert" werden, wenn eine Seite (und die Daten von vorher auf der neuen Seite veröffentlichen).

Vielen Dank an alle, die ihre Lösung veröffentlicht haben, was mich schnell zu meiner eigenen führte.

<?php
//Check if there was a post
if ($_POST) {
//Assuming there was a post, was it identical as the last time?
   if (isset($_SESSION['pastData']) AND $_SESSION['pastData'] != $_POST) {
//No, Save
   } else {
//Yes, Don't save
   }
} else {
//Save
}
//Set the session to the most current post.
$_session['pastData'] = $_POST;
?>
0
MostHost LA

Wir arbeiten an Web-Apps, in denen wir die Anzahl der PHP-Formulare erstellen. Es ist verdammt noch mal eine weitere Seite zu schreiben, um die Daten abzurufen und sie für jedes Formular einzureichen. Um eine erneute Übermittlung zu vermeiden, haben wir in jeder Tabelle ein Feld "random_check" erstellt, das als "eindeutig" gekennzeichnet ist.

Beim Laden einer Seite generieren Sie einen zufälligen Wert und speichern ihn in einem Textfeld (das offensichtlich ausgeblendet ist).

Speichern Sie diesen zufälligen Textwert bei SUBMIT im Feld 'random_check' in Ihrer Tabelle. Im Falle einer erneuten Übermittlung wird die Abfrage fehlerhaft ausgeführt, da der doppelte Wert nicht eingefügt werden kann.

Danach können Sie den Fehler gerne anzeigen

if ( !$result ) {
        die( '<script>alertify.alert("Error while saving data OR you are resubmitting the form.");</script>' );
}
0
Sandhu

Ich denke, Folgendes ist der bessere Weg, um ein erneutes Übermitteln oder Aktualisieren der Seite zu vermeiden.

$sample = $_POST['submit'];
if ($sample == "true") 
 {
//do it your code here
$sample = "false";
 }
0
Vikas Gore

Dies geschieht, wenn Sie einfach beim Aktualisieren Ihre Anfrage erneut absenden.

Also die Idee, dieses Problem durch Heilung der Ursache zu lösen.

Ich meine, wir können eine Sitzungsvariable innerhalb des Formulars einrichten und beim Update überprüfen.

if($_SESSION["csrf_token"] == $_POST['csrf_token'] )
{
// submit data  
}

//inside from 

$_SESSION["csrf_token"] = md5(Rand(0,10000000)).time(); 

<input type="hidden" name="csrf_token" value=" 
htmlspecialchars($_SESSION["csrf_token"]);"> 
0
Amul