Sometimes the user may press Enter
twice, and the post is inserted twice.
Is there a solution to prevent this other than check if there is already a post with the same title
and content
?
Sometimes the user may press Enter
twice, and the post is inserted twice.
Is there a solution to prevent this other than check if there is already a post with the same title
and content
?
Disable the submit button using Javascript once the form gets submitted (onsubmit
).
Note that if the user has disabled Javascript, they can still submit twice. Whether or not this happens often enough to justify also checking in your code (as you suggested in your question) is up to you.
disable the submit button once the user has submitted the form, using JavaScript. That is what, for example, StackOverflow uses when you answer a question.
For example
<input type="submit" onclick="this.disabled=true" />
Use a JavaScript to disable the button as soon as it is clicked.
onclick="this.disabled=true;forms[0].submit();"
Pressing submit twice quite rarely results in multiple inserts, but if you want a dead-simple sollution, use
onsubmit="document.getElementById('submit').disabled = true"
in the form tag, provided you give your submit button id="submit"
Use a unique token with the post, so that each post/postback is only handled once.
Disabling the submit button is not a very good solution since people could have javascript turned off, or doing other weird things. Client side validation is a good start, but should always be backed up with server side handling as well.
There are several solutions to this problem:
Use Javascript to disable the form's submit button when it is posted. Downside to this is that this is ABSOLUTELY not a foolproof way. It's very easy to submit forms without actually clicking the button, and this would also not work for users with JavaScript disabled. I would definitely not recommend this method.
Example:
<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>
Use PHP sessions to set a session variable (for example $_SESSION['posttimer']) to the current timestamp on post. Before actually processing the form in PHP, check if the $_SESSION['posttimer'] variable exists and check for a certain timestamp difference (IE: 2 seconds). This way, you can easily filter out double submits.
Example:
// 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();
}
Include a unique token on each POST. In this case, you would also set a session variable to the token you want to include and then render the token in the form. Once the form is submitted, you re-generate the token. When the submitted token does not match the token in your session, the form has been re-submitted and should be declared invalid.
Example:
// 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
}
}
}
Generate a unique, one-time use key to submit with the form.
Relying on Javascript is a bad idea because it may have been disabled in the client by the user. With the key scheme, when the submit is received by the server, submission for that key can be locked. You can respond to duplicate submits however you like.
For this approach to work, keys must be unique and very difficult to predict. Otherwise some forms could be locked due to key collisions. So you don't have to track keys for every form submission and avoid collisions, keys should expire with that user's session. The other thing to watch out for is if malicious users are able to predict the key, your code may be vulnerable to some kind of hijacking or DOS exploit.
I use this:
$form_token = $_SESSION['form_token'] = md5(uniqid());
send $form_token with the form, then...
I check the form_token:
if($_SESSION['form_token'] != $_POST['form_token']) {
echo 'Error';
}
The amount of answers claiming JavaScript is a viable solution is staggering (even frightening).
I weep for anybody that takes those answers seriously.