In order to avoid multiple submissions of the same form, basic recommendations are as follows:
1. Disable form submission
Once the "submit" action is done, disable it. Example technique using JavaScript:
<script type="text/javascript">
/**
Variável global "form_submited".
*/
window.form_submited = null;
/**
Função que verifica se a variável global possui o id do formulário que está sendo enviado.
*/
function AvoidMultiSubmit(frm)
{
/**
Instancia um objeto que receberá mensagens (erro, aviso, etc).
*/
frm_message = document.getElementById("form_sent_message");
/**
Compara o id do formulário atual com a variável global. Se for diferente, proseggue com o envio.
*/
if( form_submited != frm.id )
{
/**
Atribui o id do form atual a variável global.
*/
form_submited = form.id;
/**
Escreve mensagem de "loading".
*/
frm_message.innerHTML = "Os dados estão sendo processados, por favor, aguarde.";
/**
Permite o envio.
*/
return true;
}else{
/**
Escreve mensagem de "waiting".
*/
frm_message.innerHTML ="Por favor, aguarde o processamento dos dados.";
/**
Impede o envio.
*/
return false;
}
}
</script>
<div id="form_sent_message"></div>
<form id="frm1" onsubmit="return AvoidMultiSubmit(this);">
...
<form>
Why could not you just disable the button on the click (onclick) action?
The reason is that a form can be submitted by means other than the click action. Therefore, it is safest to check on the "OnSubmit" event.
2. Enhancing cookie security
Preventing multiple forms from sending is not enough because, in a simple "refresh", the user will still have the "clean" form to send again.
In order to enhance security, we need to implement a cookie verification. The following example should be embedded inside the "AvoidMultiSubmit" function, in the conditional that sends the form:
var name = "cookie_frm1"; // nome do cookie
var value = "submited"; // um valor qualquer
var days = 1; // quantidade de dias de expiração
/**
Formata os parâmetros
*/
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires=""+date.toGMTString();
/**
Cria o cookie
*/
document.cookie = name+"="+value+expires+"; path=/";
In the PHP script that receives the data, make sure the cookie exists:
if( isset( $_COOKIE['cookie_frm1'] ) )
{
echo 'Ação negada';
exit;
}
Note: PHP blocking can be a redirect or contain another type of message that is more user-friendly. The above example is purely didactic.
When completing PHP runs, if you do not need to return to the form, remove the cookie:
unset( $_COOKIE['cookie_frm1'] )