Avatar billede mjansen Seniormester
07. februar 2016 - 19:05 Der er 11 kommentarer

Form submit og undgå dobbelt op ved opdatering

Hej

Har lavet et forum.

Virker fint, men hvis jeg laver en opdatering kommer indlægget 2 gange ikke smart.

Hvordan undgår I dobbelt oprettelse i forbindelse med form og opdatering??
Avatar billede moddi100 Seniormester
07. februar 2016 - 19:40 #1
Du har en del forskellige muligheder, herunder et par forskellige:

1) Brug AJAX (javascript) til at poste data
2) Generer et token, som du så husker i en $_SESSION. Ved post kan du så se om det aktuelle token allerede er brugt eller ej. Dette modvirker også XSS angreb
3) Post data normalt, redirect ved brug af php's header() funktion.

Samt mange flere. Det nemmeste at implementere er 3), selvom jeg personligt mest hælder til 2) grundet den ekstra sikkerhed
Avatar billede jakobdo Ekspert
07. februar 2016 - 20:31 #2
Som moddi siger, er nummer 3 nok den nemmeste at lave.

Din form:

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

//post.php
//Gem data i databasen.
header("Location: form.php");
exit();

Og dermed bliver brugeren lige sendt "væk" fra form.php og kan derfor ikke "spamme" dit forum med F5 og sende den samme besked igen og igen.
Avatar billede mjansen Seniormester
07. februar 2016 - 21:58 #3
Mulighed 3 er ikke lige pt. så let, da der allerede er sendt data til browseren når dette POST håndteres.

Og da det er en del at et større system, vil jeg være ked af at rette på det pt.

Har aldrig fundet SESSION nødvendig til det jeg har lavet, men måske det er tiden at kigge på det nu.

Måske man kunne få en lille guide?
Avatar billede moddi100 Seniormester
07. februar 2016 - 22:27 #4
Angående 3) så kan ob_start() og ob_end_flush() lave underværker.

Men i princippet kan du lave et $_SESSION-array med en liste over valide tokens. Altså i din form:

form.php
<?php
session_start();

// Step 1: Generer token
// NB: Dette er en hurtig måde at generere tokens på, langt fra den bedste
$token = md5(microtime(true));

// Step 2: Gem token i session
$_SESSION['tokens'][$token] = true;

?>
<html>
...
<form action="action.php" method="post">
<?php

// Step 3: Udskriv token til form
echo '<input type="hidden" name="token" value="' . $token . '" />';

?>

<!-- Resten af din formular her -->
</form>
...
</html>


Dette var din form. Hver kan siden indlæses, skal der altså genereres et nyt token. Der kan på altså eksistere flere tokens sideløbende. Det er en væsentlig detalje! Videre til din håndtering af data:

action.php
<?php
session_start();

$token = $_POST['token'];

// Step 4: Kontroller om token er gyldigt
if(empty($token) || !isset($_SESSION['tokens']) || !array_key_exists($token, $_SESSION['tokens']))
{
  // Ugyldigt token. Det er allerede blevet anvendt
  die("Dine data er allerede blevet gemt");
} else {
  // Step 5: Gem de indtastede data

  // Step 6: Fjern token, så det ikke kan anvendes igen
  unset($_SESSION['tokens'][$token]);
}?>
Avatar billede arne_v Ekspert
09. februar 2016 - 01:56 #5
Redirect er vel ikke 100% sikker????

(hvis andet submit sker inden response paa foerste submit er naaet tilbage til browser)
Avatar billede arne_v Ekspert
09. februar 2016 - 01:57 #6
AJAX forhindrer heller ikke dobbelt klik.
Avatar billede arne_v Ekspert
09. februar 2016 - 02:00 #7
Den rigtigte loesning er at gemme noget i session.

Det haandterer alle situationer med reload, utaalmodigt klik igen etc..

Det er ogsaa kendt som:

synchronizer token pattern
Avatar billede moddi100 Seniormester
09. februar 2016 - 17:02 #8
arne_v: Enig i at redirect ikke er 100% sikker, men den er til gengæld ret ligetil.

AJAX kan ikke stå alene, men deaktiveres knappen nu samtidig med klik, så kan dette undgås.

Og helt enig i #7, hvilket dog samtidig er den mest besværlige vej - men også den optimale
Avatar billede mjansen Seniormester
16. marts 2016 - 12:45 #9
Har desværre ikke haft tid til at komme videre endnu.

Men vil helt klart gå session vejen.

Arne har du et let eksempel?
Avatar billede moddi100 Seniormester
16. marts 2016 - 13:02 #10
Se #4
Avatar billede arne_v Ekspert
19. marts 2016 - 18:08 #11
#4 viser en maade at goere det paa.

Men jeg ville nok lave det lidt anderledes. Som minimum bytte om paa step 5 og 6.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester