Folks, I know this topic has been hashed to death, but after reading many answered questions here, I'm no closer to a solution.
The problem: after submitting a form, even with Post-Redirect-Get, users can still press the back button to return to the original form, which will be exactly as it was when posted. Users can then just press the submit button to send the same data again.
I realize it's bad practice to try to disable the back button, so I would like either: 1.- to be able to clear the form so that the data the user entered is no longer there when returning to the posted form via back button. 2.- to be able to distinguish in code between original form submission and repeat form submission.
I've been reading that you can accomplish #2 with a random number. In Stop data inserting into a database twice I read
I use nonces ("number used once") for forms where resubmission is a problem. Create a random number/string, store it in the session data and add it to the form as a hidden field. On form submission, check that the POSTed value matches the session value, then immediately clear the session value. Resubmission will fail. (James Socol)
Seem clear enough but I can't seem to get that to work. Here's skeletal code, as brief as I can make it. I've single-stepped through it. When I press the back button, the PHP code starts executing from the start. $_SERVER['REQUEST_METHOD']
returns GET
so it's as if the form has not been posted, and the code falls through and generates a new random number. When the form is submitted (the second time), $_SESSION['rnd']
equals $_POST['rnd']
so the resubmitted form is processed as if it were the first time.
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($_SESSION['rnd'] == $_POST['rnd']) {
$form_data = $_POST; //process form
$_SESSION['rnd'] = 0;
$msg = 'data posted';
}
else {
$msg = 'cannot post twice';
}
}
else {
$msg = 'ready to post';
$rnd = rand(100,999);
$_SESSION['rnd'] = $rnd;
}
?>
<html>
<head>
<title>app page</title>
</head>
<body>
<h1>app page</h1>
<h3><?= $msg ?></h3>
<form method="post">
Field 1: <input type="text" name="field1"
value="<?= (isset($form_data['field1']) ? $form_data['field1'] : '') ?>">
<input type="submit" name="submit" value="Ok">
<input type="hidden" name="rnd" value="<?= (isset($rnd) ? $rnd : $_POST['rnd']) ?>">
</form>
</body>
</html>
Thanks for any insight. I realize the above code does not implement PRG, but I think it doesn't matter. The issue isn't an F5 refresh but a back button refresh.