Ik heb een contactformulier waarin de afhandeling en het formulier in hetzelfde PHP bestand zitten. Ik gebruik POST variabelen.
Nu heb ik last van het bekende probleem dat na verzending het formulier opnieuw verzonden wordt als ik de pagina ververs. Voor zover ik weet is het niet mogelijk om de POST variabelen leeg te maken direct na verzending, omdat ze nog in het geheugen van de browser zitten.
Heeft iemand hier een idee wat te doen om dit probleem te voorkomen?
Je kunt je beter bedienen van output escaping in plaats van strip_tags() lijkt mij? strip_tags() is in zekere zin ook een "black list" - het vertelt je alleen maar wat niet toegestaan is, en niet zozeer wat wel toegestaan is. strip_tags() helpt je ook niet echt om te voorkomen dat formulieren breken, bijvoorbeeld door de introductie van dubbele quotes en dergelijke...
Het is ook niet nodig om eerst te controleren of een sessie "bestaat" middels isset() - session_start() wordt gebruikt om een sessie te starten en/of voort te zetten.
Het ding is gewoon, op het moment dat je met formulieren aan de slag gaat kom je in een gebied terecht dat een overlap heeft met andere zaken, hier komen een aantal zaken bij elkaar die elk op een juiste wijze behandeld zouden moeten worden.
<?php
if( Csrf::isTokenValid( $_POST['csrf_token'] ) ) {
echo "De code is gevalideerd";
} else {
echo "Nope, de code is niet gevalideerd! Je bent van een ongewenste website";
}
?>
>> Het gaat mij er dus om hoe ik ná de afhandeling weer terug ga naar form.php en daar mijn foutmelding toon, en dus zonder gebruik te maken van de header location.
door je formulier naar form.php te posten en lekker daar te blijven totdat de validatie van het formulier geslaagd is en de gegevens van het formulier verwerkt zijn.
[size=xsmall]Toevoeging op 24/09/2018 11:43:11:[/size]
<?php
// functie die de formuliervelden valideert en foutmeldingen aanmaakt
function validate($naam, $email)
{
$errors = array();
// validatieregels voor de naam
if(strlen($naam) < 2)
$errors['naam'] = 'U heeft geen naam ingevuld.';
// validatieregels voor het mailadres
if(!strlen($email))
$errors['email'] = 'U heeft geen email adres ingevuld.';
else if(!filter_var($email, FILTER_VALIDATE_EMAIL))
$errors['email'] = 'U heeft een ongeldig email adres ingevuld.';
// geef de array met foutmeldingen terug
return $errors;
}
// initialisatie
$naam = '';
$email = '';
$errors = array();
// indien het formulier verstuurd is
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
// overschrijf de variabelen met de waarde uit de $_POST array
$naam = $_POST['naam'];
$email = $_POST['email'];
// valideer de ingevulde gegevens
$errors = validate($_POST['naam'], $_POST['email']);
// als geen fouten voortkomen uit de validatie
if(!count($errors))
{
/*
* Verwerk hier je formulier, bijvoorbeeld een email versturen of
* de gegevens opslaan in de database
*/
// redirect de gebruiker
header('Location: confirmation.html');
exit;
}
}
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Mijn eerste formulier</title>
</head>
<body>
<?php
if(count($errors)) {
echo '<ul id="errors">';
foreach($errors as $error) {
echo '<li>' . $error . '</li>';
}
echo '</ul>';
}
?>
<form method="post">
<input type="text" name="naam" value="<?php echo $naam ?>" />
<input type="email" name="email" value="<?php echo $email ?>" />
<button type="submit">Verzenden</button>
</form>
</body>
</html>
Bedankt voor jullie reacties. Genoeg stof om me in te verdiepen!
@Ariën: zal me later es verdiepen in een token... eerst maar de opbouw van mijn formulier goed krijgen ;-)
@Frank: bedankt voor je voorbeeld. Ik kan de gebruiker natuurlijk ook redirecten naar dezelfde pagina nadat formulier verstuurd is (nog niet getest):
Het hele idee van een CSRF-token is toch juist dat deze een "one time use" heeft? Dat ding hierboven heeft een geldigheidsdatum van een dag?!
Nadat het formulier succesvol is verwerkt moet dit token direct ongeldig gemaakt worden. Of sterker nog, na elke submitpoging zou dit token ongeldig moeten zijn.
>> @Frank: bedankt voor je voorbeeld. Ik kan de gebruiker natuurlijk ook redirecten naar dezelfde pagina nadat formulier verstuurd is (nog niet getest)
Bij een redirect gaat je form data (je $_POST array) verloren. De gebruiker moet dan vervolgens zijn formulier weer helemaal opnieuw invullen hetgeen niet erg gebruiksvriendelijk is. Zo ook voor de foutmeldingen die je boven of in het formulier wilt tonen. Natuurlijk zijn er lapmiddelen te bedenken met GET variabelen of met behulp van $_SESSION maar dat zou het alleen maar nodeloos ingewikkeld maken.
Natuurlijk zijn er lapmiddelen te bedenken met GET variabelen
Eigenlijk zou je GET alleen maar voor (onpersoonlijke) zoekopdrachten moeten gebruiken of bijvoorbeeld zaken als pagina-navigatie. URLs kunnen mogelijk gecached worden door tussenstations (proxy's). Zelfs HTTPS gaat je dan waarschijnlijk niet helpen. Betreft het persoonlijke/gevoelige informatie --> gebruikt POST.
@Frank:
in jouw voorbeeld gebruik je alleen een header location als formulier correct ingevuld is, dus maakt het dan niet meer uit of de POST array verloren gaat. Ik toon immers alleen nog een Dank U bericht. Of zie ik iets over het hoofd?
Als alles goed is gegaan, waarom zou je de informatie uit je POST dan willen behouden?
Of wil je jouw site zo vriendelijk maken dat bij een volgende vraag via het contactformulier de naam standaard ingevuld is?