wake-up-neo.com

Wie vermeide ich mehrfache Einfügungen, wenn ich ein Formular in PHP abschicke?

Manchmal drückt der Benutzer zweimal Enter und der Beitrag wird zweimal eingefügt.

Gibt es eine andere Lösung, um dies zu verhindern, als zu prüfen, ob bereits ein Beitrag mit derselben title und content vorhanden ist?

29
user198729

Es gibt mehrere Lösungen für dieses Problem:

  1. Nutze Javascript, um die Absenden-Schaltfläche des Formulars zu deaktivieren, wenn es gepostet wird. Nachteil ist, dass dies absolut kein narrensicherer Weg ist. Es ist sehr einfach, Formulare zu senden, ohne auf die Schaltfläche zu klicken. Dies funktioniert auch nicht für Benutzer mit deaktiviertem JavaScript.Ich würde diese Methode definitiv nicht empfehlen.

    Beispiel:

    <script language="javascript">
    <!--
        function disableSubmitButton() {
            // you may fill in the blanks :)
        }
    -->
    </script>
    <form action="foo.php" method="post">
        <input type="text" name="bar" />
        <input type="submit" value="Save" onclick="disableSubmitButton();">
    </form>
    
  2. Verwenden Sie PHP sessions , um eine Sitzungsvariable (zum Beispiel $ _SESSION ['posttimer']) auf den aktuellen Zeitstempel zu setzen. Bevor Sie das Formular tatsächlich in PHP verarbeiten, prüfen Sie, ob die Variable $ _SESSION ['posttimer'] vorhanden ist, und prüfen Sie, ob ein bestimmter Zeitstempel vorliegt (IE: 2 Sekunden). Auf diese Weise können Sie Doppeleinträge problemlos herausfiltern.

    Beispiel:

    // form.html
    <form action="foo.php" method="post">
        <input type="text" name="bar" />
        <input type="submit" value="Save">
    </form>
    
    // foo.php
    if (isset($_POST) && !empty($_POST)) 
    {
        if (isset($_SESSION['posttimer']))
        {
            if ( (time() - $_SESSION['posttimer']) <= 2)
            {
                // less then 2 seconds since last post
            }
            else
            {
                // more than 2 seconds since last post
            }
        }
        $_SESSION['posttimer'] = time();
    }
    
  3. Ein eindeutiges Token für jeden POST hinzufügen. In diesem Fall würden Sie auch eine Sitzungsvariable auf das Token setzen, das Sie einschließen möchten, und dann das Token im Formular darstellen. Nach dem Senden des Formulars generieren Sie das Token erneut. Wenn das übergebene Token nicht mit dem Token in Ihrer Sitzung übereinstimmt, wurde das Formular erneut übermittelt und sollte für ungültig erklärt werden.

    Beispiel:

    // form.php
    <?php
        // obviously this can be anything you want, as long as it is unique
        $_SESSION['token'] = md5(session_id() . time());
    ?>
    <form action="foo.php" method="post">
        <input type="hidden" name="token" value="<?php echo $_SESSION['token'] ?>" />
        <input type="text" name="bar" />
        <input type="submit" value="Save" />
    </form>
    
    // foo.php
    if (isset($_SESSION['token']))
    {
        if (isset($_POST['token']))
        {
            if ($_POST['token'] != $_SESSION['token'])
            {
                // double submit
            }
        }
    }
    
48
Aron Rotteveel

Verwenden Sie ein eindeutiges Token für den Post, sodass jedes Post/Postback nur einmal behandelt wird.

Das Deaktivieren der Schaltfläche "Senden" ist keine sehr gute Lösung, da die Benutzer Javascript deaktiviert haben oder andere seltsame Dinge tun könnten. Die clientseitige Validierung ist ein guter Anfang, sollte jedoch immer auch mit serverseitigem Handling gesichert werden.

30

Generieren Sie einen eindeutigen, einmaligen Verwendungsschlüssel, der mit dem Formular übermittelt werden soll.

Sich auf Javascript zu verlassen, ist eine schlechte Idee, da es möglicherweise vom Benutzer im Client deaktiviert wurde. Mit dem Schlüsselschema kann die Übermittlung für diesen Schlüssel gesperrt werden, wenn der Server die Übermittlung empfängt. Sie können auf doppelte Einsendungen beliebig antworten.

Für diese Arbeitsweise müssen Schlüssel eindeutig und schwer vorhersagbar sein. Ansonsten könnten manche Formulare aufgrund von Schlüsselkollisionen gesperrt werden. Sie müssen also nicht bei jeder Formularübermittlung Schlüssel nachverfolgen und Kollisionen vermeiden. Die Schlüssel sollten mit der Benutzersitzung ablaufen. Die andere Sache, auf die Sie achten sollten, ist, wenn böswillige Benutzer den Schlüssel vorhersagen können, Ihr Code möglicherweise anfällig für eine Art Hijacking oder DOS-Exploit ist. 

5
Dana the Sane

Doppelte Formularübermittlung verhindern zeigt eine Möglichkeit, dies ohne Javascript zu tun.

2
Javi

Ich benutze das:

$form_token = $_SESSION['form_token'] = md5(uniqid());

$ form_token mit dem Formular senden, dann ...

Ich überprüfe das form_token:

if($_SESSION['form_token'] != $_POST['form_token']) {
   echo 'Error';
}
1
CSSJediEsck21

Deaktivieren Sie die Schaltfläche zum Senden mit Javascript, sobald das Formular gesendet wurde (onsubmit).

Wenn der Benutzer Javascript deaktiviert hat, kann er dennoch zweimal senden. Ob dies oft genug geschieht oder nicht, um das Einchecken Ihres Codes (wie Sie es in Ihrer Frage vorgeschlagen haben) zu rechtfertigen, liegt bei Ihnen.

1
Aistina

Verwenden Sie alternativ einmalige Formularschlüssel.

1
mst

Eine andere Möglichkeit, eine Bestätigungsseite zu erstellen, auf der der Benutzer die Schaltfläche "Senden" drücken kann. Es könnte die Möglichkeiten dieser Art reduzieren. 

0

Ich mache folgendes auf der action.php 

if($_SESSION && isset($_SESSION['already_submitted'])) {

  # If already submitted just redirect to thank you page

} else {

    # If first submit then assign session value and process the form
    $_SESSION['already_submitted'] = true;

    # Process form

}

Anmerkung: Initiieren Sie Ihre Sitzungen immer mit header_start () im Header.

0
Robert Sinclair

deaktivieren Sie die Schaltfläche "Senden", sobald der Benutzer das Formular gesendet hat, und verwenden Sie dazu JavaScript. Das ist, was StackOverflow zum Beispiel verwendet, wenn Sie eine Frage beantworten. 

Zum Beispiel

<input type="submit" onclick="this.disabled=true" />
0
Marius

Verwenden Sie JavaScript, um die Schaltfläche zu deaktivieren, sobald Sie darauf klicken.

onclick="this.disabled=true;forms[0].submit();"
0
Joel Etherton

Das zweimalige Drücken von "Senden" führt ziemlich oft zu mehreren Einfügungen. Wenn Sie jedoch eine ganz einfache Lösung wünschen, verwenden Sie

onsubmit="document.getElementById('submit').disabled = true"

im Formular-Tag, vorausgesetzt, Sie geben den Absenden-Button id="submit"

0
raveren