Às vezes, quando a resposta é lenta, pode-se clicar no botão enviar várias vezes.
Como evitar que isso aconteça?
Às vezes, quando a resposta é lenta, pode-se clicar no botão enviar várias vezes.
Como evitar que isso aconteça?
Respostas:
Use javascript discreto para desativar o evento de envio no formulário após ele já ter sido enviado. Aqui está um exemplo usando jQuery.
EDIT: Corrigido o problema com o envio de um formulário sem clicar no botão de envio. Obrigado, Ichiban.
$("body").on("submit", "form", function() {
$(this).submit(function() {
return false;
});
return true;
});
return true
? Acho que o envio inicial deve funcionar sem isso.
return true
está implícito se omitido.
$(this).find("input[type='submit']").attr('disabled', 'disabled').val('submiting'); return true; });
Tentei a solução de vanstee junto com a validação discreta do asp mvc 3 e, se a validação do cliente falhar, o código ainda será executado e o envio do formulário será desativado para sempre. Não consigo reenviar após corrigir os campos. (veja o comentário de bjan)
Então eu modifiquei o script de vanstee assim:
$("form").submit(function () {
if ($(this).valid()) {
$(this).submit(function () {
return false;
});
return true;
}
else {
return false;
}
});
O controle de envio do formulário do lado do cliente pode ser alcançado de forma bastante elegante, fazendo com que o manipulador onsubmit oculte o botão de envio e o substitua por uma animação de carregamento. Dessa forma, o usuário obtém feedback visual imediato no mesmo local onde sua ação (o clique) aconteceu. Ao mesmo tempo, você evita que o formulário seja enviado em outra ocasião.
Se você enviar o formulário via XHR, lembre-se de que você também deve lidar com erros de envio, por exemplo, tempo limite. Você teria que exibir o botão de envio novamente porque o usuário precisa reenviar o formulário.
Por outro lado, llimllib traz um ponto muito válido. Toda validação de formulário deve acontecer no lado do servidor. Isso inclui várias verificações de envio. Nunca confie no cliente! Este não é o caso apenas se o javascript estiver desativado. Você deve ter em mente que todo código do lado do cliente pode ser modificado. É um pouco difícil de imaginar, mas o html / javascript falando com o seu servidor não é necessariamente o html / javascript que você escreveu.
Como o llimllib sugere, gere o formulário com um identificador exclusivo para esse formulário e coloque-o em um campo de entrada oculto. Armazene esse identificador. Ao receber dados do formulário, processe-os apenas quando o identificador corresponder. (Também vincular o identificador à sessão do usuário e corresponder a isso, também, para segurança extra.) Após o processamento de dados, exclua o identificador.
Obviamente, de vez em quando, você precisa limpar os identificadores para os quais nunca foram enviados dados de formulário. Mas provavelmente seu site já emprega algum tipo de mecanismo de "coleta de lixo".
<form onsubmit="if(submitted) return false; submitted = true; return true">
<form onsubmit="return (typeof submitted == 'undefined') ? (submitted = true) : !submitted">
, ou escrever var submitted = false;
no ponto certo do seu script, para evitar o seguinte erro: Uncaught ReferenceError: submitted is not defined
.
Esta é uma maneira simples de fazer isso:
<form onsubmit="return checkBeforeSubmit()">
some input:<input type="text">
<input type="submit" value="submit" />
</form>
<script type="text/javascript">
var wasSubmitted = false;
function checkBeforeSubmit(){
if(!wasSubmitted) {
wasSubmitted = true;
return wasSubmitted;
}
return false;
}
</script>
Desative o botão de envio logo após um clique. Certifique-se de lidar com as validações corretamente. Além disso, mantenha uma página intermediária para todas as operações de processamento ou banco de dados e, em seguida, redirecione para a próxima página. Isso garante que Atualizar a segunda página não faça outro processamento.
form page ---submits to---> form_submission_script.php ---after saving, redirects to---> form_thankyou.html
Hash a hora atual, torne-a uma entrada oculta no formulário. No lado do servidor, verifique o hash de cada envio de formulário; se você já recebeu esse hash, então você repetiu o envio.
editar: depender de javascript não é uma boa ideia, então todos vocês podem continuar votando nessas ideias, mas alguns usuários não os habilitarão. A resposta correta é não confiar na entrada do usuário no lado do servidor.
Usando JQuery, você pode fazer:
$('input:submit').click( function() { this.disabled = true } );
E
$('input:submit').keypress( function(e) {
if (e.which == 13) {
this.disabled = true
}
}
);
Sei que você marcou sua pergunta com 'javascript', mas aqui está uma solução que não depende de javascript de forma alguma:
É um padrão de webapp chamado PRG , e aqui está um bom artigo que o descreve
Você pode evitar o envio múltiplo simplesmente com:
var Workin = false;
$('form').submit(function()
{
if(Workin) return false;
Workin =true;
// codes here.
// Once you finish turn the Workin variable into false
// to enable the submit event again
Workin = false;
});
Workin =true;
. Submissões duplas ainda são possíveis, mas menos são prováveis.
A resposta mais simples para esta pergunta: "Às vezes, quando a resposta é lenta, pode-se clicar no botão enviar várias vezes. Como evitar que isso aconteça?"
Apenas desative o botão de envio do formulário, como o código abaixo.
<form ... onsubmit="buttonName.disabled=true; return true;">
<input type="submit" name="buttonName" value="Submit">
</form>
Isso irá desabilitar o botão enviar, no primeiro clique para enviar. Além disso, se você tiver algumas regras de validação, funcionará bem. Espero que ajude.
Do lado do cliente , você deve desabilitar o botão de envio assim que o formulário for enviado com o código javascript, como o método fornecido por @vanstee e @chaos.
Mas há um problema de atraso de rede ou situação de javascript desabilitado em que você não deve confiar no JS para evitar que isso aconteça.
Portanto, no lado do servidor , você deve verificar o envio repetido dos mesmos clientes e omitir o repetido que parece uma tentativa falsa do usuário.
Você pode tentar o plugin jquery do safeform .
$('#example').safeform({
timeout: 5000, // disable form on 5 sec. after submit
submit: function(event) {
// put here validation and ajax stuff...
// no need to wait for timeout, re-enable the form ASAP
$(this).safeform('complete');
return false;
}
})
A solução mais simples e elegante para mim:
function checkForm(form) // Submit button clicked
{
form.myButton.disabled = true;
form.myButton.value = "Please wait...";
return true;
}
<form method="POST" action="..." onsubmit="return checkForm(this);">
...
<input type="submit" name="myButton" value="Submit">
</form>
Isso permite o envio a cada 2 segundos. Em caso de validação frontal.
$(document).ready(function() {
$('form[debounce]').submit(function(e) {
const submiting = !!$(this).data('submiting');
if(!submiting) {
$(this).data('submiting', true);
setTimeout(() => {
$(this).data('submiting', false);
}, 2000);
return true;
}
e.preventDefault();
return false;
});
})
a melhor forma de evitar o envio de múltiplos é passando o id do botão no método.
function DisableButton() {
document.getElementById("btnPostJob").disabled = true;
}
window.onbeforeunload = DisableButton;
Fazer isso usando javascript é um pouco fácil. A seguir está o código que dará a funcionalidade desejada:
$('#disable').on('click', function(){
$('#disable').attr("disabled", true);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="disable">Disable Me!</button>
As soluções mais simples são desabilitar o botão ao clicar e habilitá-lo após a conclusão da operação. Para verificar uma solução semelhante no jsfiddle:
[click here][1]
E você pode encontrar alguma outra solução para esta resposta .
Isso funciona muito bem para mim. Ele envia a fazenda e desativa o botão e, após 2 segundos, ativa o botão.
<button id="submit" type="submit" onclick="submitLimit()">Yes</button>
function submitLimit() {
var btn = document.getElementById('submit')
setTimeout(function() {
btn.setAttribute('disabled', 'disabled');
}, 1);
setTimeout(function() {
btn.removeAttribute('disabled');
}, 2000);}
Em ECMA6 Syntex
function submitLimit() {
submitBtn = document.getElementById('submit');
setTimeout(() => { submitBtn.setAttribute('disabled', 'disabled') }, 1);
setTimeout(() => { submitBtn.removeAttribute('disabled') }, 4000);}
Apenas para adicionar às respostas possíveis sem burlar a validação de entrada do navegador
$( document ).ready(function() {
$('.btn-submit').on('click', function() {
if(this.form.checkValidity()) {
$(this).attr("disabled", "disabled");
$(this).val("Submitting...");
this.form.submit();
}
});
});
Uma alternativa ao que foi proposto antes é:
jQuery('form').submit(function(){
$(this).find(':submit').attr( 'disabled','disabled' );
//the rest of your code
});