Voorkomen dat formulier opnieuw wordt ingediend

Pagina één bevat een HTML-formulier. Pagina twee – de code die de ingediende gegevens verwerkt.

Het formulier op pagina één wordt verzonden. De browser wordt omgeleid naar pagina twee. Pagina twee behandelt de ingediende gegevens.

Als pagina twee op dit moment wordt vernieuwd, verschijnt er een waarschuwing ‘Opnieuw indienen van formulier’.

Kan dit worden voorkomen?


Antwoord 1, autoriteit 100%

Er zijn twee benaderingen die mensen hier gebruikten:

Methode 1:AJAX + Redirect gebruiken

Op deze manier post je je formulier op de achtergrond met JQuery of iets vergelijkbaars met Page2, terwijl de gebruiker pagina1 nog steeds ziet. Na succesvol posten, stuurt u de browser om naar Page2.

Methode 2:Post + Redirect naar zichzelf

Dit is een veelgebruikte techniek op forums. Form on Page1 plaatst de gegevens op Page2, Page2 verwerkt de gegevens en doet wat moet worden gedaan, en vervolgens voert het een HTTP-omleiding op zichzelf uit. Op deze manier is de laatste “actie” die de browser onthoudt een simpele GET op pagina2, zodat het formulier niet opnieuw wordt ingediend bij F5.


Antwoord 2, autoriteit 17%

Je moet PRG – Post/Redirect/Get patroon gebruikenen je hebt zojuist de P van PRG geïmplementeerd. U moet Omleiden.(Tegenwoordig heeft u helemaal geen omleiding nodig. Zie dit)

PRG is een ontwerppatroon voor webontwikkeling dat dubbele formulierinzendingen voorkomt, wat betekent: Formulier indienen (Post Request 1) -> Omleiden -> Ontvang (verzoek 2)

Under the hood

Omleidingsstatuscode– HTTP 1.0 met HTTP 302 of HTTP 1.1 met HTTP 303

Een HTTP-antwoord met omleidingsstatuscode levert bovendien een URL op in het locatiekoptekstveld. De user-agent (bijv. een webbrowser) wordt door een reactie met deze code uitgenodigd om een ​​tweede, overigens identieke, aanvraag te doen naar de nieuwe URL die is opgegeven in het locatieveld.

De omleidingsstatuscode is om ervoor te zorgen dat in deze situatie de browser van de internetgebruiker de serverreactie veilig kan vernieuwen zonder dat het initiële HTTP POST-verzoek opnieuw moet worden ingediend.

Double Submit Problem

Probleem met dubbele indiening

Post/Redirect/Get Solution

Post/Redirect/Get Solution

Bron


Antwoord 3, autoriteit 7%

Direct, dat kan niet, en dat is maar goed ook. De waarschuwing van de browser is er met een reden. Deze thread zou je vraag moeten beantwoorden:

Voorkomen dat de knop Terug de POST-bevestigingswaarschuwing weergeeft

Twee belangrijke voorgestelde oplossingen waren het PRG-patroon en een AJAX-indiening gevolgd door een scriptverplaatsing.

Houd er rekening mee dat als uw methode een GET toestaat en geen POST-verzendmethode, dat zowel het probleem zou oplossen als beter zou passen bij de conventie. Deze oplossingen worden geleverd in de veronderstelling dat u gegevens wilt/moet POST.


Antwoord 4, autoriteit 6%

De enige manier om er 100% zeker van te zijn dat hetzelfde formulier nooit twee keer wordt ingediend, is door een unieke identificatiecode in te voegen in elk formulier dat u uitgeeft en bij te houden welke op de server zijn ingediend. De valkuil is dat als de gebruiker een back-up maakt naar de pagina waar het formulier stond en nieuwe gegevens invoert, hetzelfde formulier niet werkt.


Antwoord 5, autoriteit 4%

Het antwoord bestaat uit twee delen:

  1. Zorg ervoor dat dubbele berichten niet knoeien met uw gegevens aan de serverzijde. Om dit te doen, sluit u een unieke identifier in de post in, zodat u volgende verzoeken aan de serverzijde kunt weigeren. Dit patroon wordt in berichtentermen Idempotent Receivergenoemd.

  2. Zorg ervoor dat de gebruiker geen last heeft van de mogelijkheid van dubbele inzendingen door beide

    • omleiden naar een GET na de POST (POST-omleiding GET-patroon)
    • de knop uitschakelen met javascript

Niets wat je doet onder 2. zal dubbele inzendingen volledig voorkomen. Mensen kunnen heel snel klikken en hackers kunnen toch posten. Je hebt altijd 1. nodig als je absoluut zeker wilt zijn dat er geen duplicaten zijn.


Antwoord 6, autoriteit 3%

U kunt de methode replaceStatevan JQuery gebruiken:

<script>
   $(document).ready(function(){
   window.history.replaceState('','',window.location.href)
   });
</script>

Dit is de meest elegante manier om te voorkomen dat gegevens opnieuw worden verzonden nadat ze zijn verzonden vanwege een terugkoppeling.

Hopelijk helpt dit.


Antwoord 7

Als u een pagina vernieuwt met POST-gegevens, bevestigt de browser uw herindiening. Als u GET-gegevens gebruikt, wordt het bericht niet weergegeven. U kunt ook de tweede pagina, na het opslaan van de inzending, laten omleiden naar een derde pagina zonder gegevens.


Antwoord 8

Nou, ik ontdekte dat niemand deze truc noemde.

Zonder omleiding kunt u de formulierbevestiging bij het vernieuwen nog steeds voorkomen.

Standaard is de formuliercode als volgt:

<form method="post" action="test.php">

nu, verander het in
<form method="post" action="test.php?nonsense=1">

Je zult de magie zien.

Ik denk dat het komt omdat browsers de pop-up met bevestigingswaarschuwingen niet activeren als er een GET-methode (querystring) in de url staat.


Antwoord 9

Het PRG-patroon kan alleen voorkomen dat de pagina opnieuw wordt verzonden. Dit is geen 100% veilige maatregel.

Meestal onderneem ik onderstaande acties om herindiening te voorkomen:

  1. Client Side – Gebruik javascript om dubbele klikken op een knop te voorkomen die het indienen van formulieren activeert. Je kunt de knop gewoon uitschakelen na de eerste klik.

  2. Serverzijde – Ik bereken een hash op de ingediende parameters en sla die hash op in een sessie of database, zodat wanneer de gedupliceerde inzending is ontvangen, we de duplicatie kunnen detecteren en vervolgens de juiste reactie naar de klant kunnen sturen. U kunt er echter in slagen om een ​​hash aan de clientzijde te genereren.

In de meeste gevallen kunnen deze maatregelen helpen om herindiening te voorkomen.


Antwoord 10

Ik vind het antwoord van @Angelin erg leuk. Maar als je te maken hebt met verouderde code waar dit niet praktisch is, kan deze techniek voor jou werken.

Bovenaan het bestand

// Protect against resubmits
if (empty($_POST))  {
   $_POST['last_pos_sub'] = time();
} else {
     if (isset($_POST['last_pos_sub'])){
        if ($_POST['last_pos_sub'] == $_SESSION['curr_pos_sub']) {
           redirect back to the file so POST data is not preserved
        }
        $_SESSION['curr_pos_sub'] = $_POST['last_pos_sub'];
     }
}

Vervolgens aan het einde van het formulier, plak je last_pos_subals volgt in:

<input type="hidden" name="last_pos_sub" value=<?php echo $_POST['last_pos_sub']; ?>>

Antwoord 11

Probeer tris:

function prevent_multi_submit($excl = "validator") {
    $string = "";
    foreach ($_POST as $key => $val) {
    // this test is to exclude a single variable, f.e. a captcha value
    if ($key != $excl) {
        $string .= $key . $val;
    }
    }
    if (isset($_SESSION['last'])) {
    if ($_SESSION['last'] === md5($string)) {
        return false;
    } else {
        $_SESSION['last'] = md5($string);
        return true;
    }
    } else {
    $_SESSION['last'] = md5($string);
    return true;
    }
}

Hoe te gebruiken / voorbeeld:

if (isset($_POST)) {
    if ($_POST['field'] != "") { // place here the form validation and other controls
    if (prevent_multi_submit()) { // use the function before you call the database or etc
        mysql_query("INSERT INTO table..."); // or send a mail like...
        mail($mailto, $sub, $body); // etc
    } else {
        echo "The form is already processed";
    }
    } else {
    // your error about invalid fields
    }
}

Lettertype: https://www.tutdepot.com/prevent-multiple- form-submission/


Antwoord 12

gebruik js om het toevoegen van gegevens te voorkomen:

if ( window.history.replaceState ) {
    window.history.replaceState( null, null, window.location.href );
}

Other episodes