A veces, cuando la respuesta es lenta, se puede hacer clic en el botón enviar varias veces.
¿Cómo evitar que esto suceda?
A veces, cuando la respuesta es lenta, se puede hacer clic en el botón enviar varias veces.
¿Cómo evitar que esto suceda?
Respuestas:
Use javascript discreto para deshabilitar el evento de envío en el formulario después de que ya se haya enviado. Aquí hay un ejemplo usando jQuery.
EDITAR: Se solucionó el problema al enviar un formulario sin hacer clic en el botón Enviar. Gracias, ichiban.
$("body").on("submit", "form", function() {
$(this).submit(function() {
return false;
});
return true;
});
return true
? Creo que el envío inicial debería funcionar sin eso.
return true
está implícito si se omite.
$(this).find("input[type='submit']").attr('disabled', 'disabled').val('submiting'); return true; });
Lo intenté la solución de vanstee junto con ASP MVC 3 de validación discreto, y si falla la validación del cliente, el código es todavía corro, y formulario de envío está desactivada para siempre. No puedo volver a enviar después de corregir los campos. (ver el comentario de bjan)
Así que modifiqué el guión de vanstee de esta manera:
$("form").submit(function () {
if ($(this).valid()) {
$(this).submit(function () {
return false;
});
return true;
}
else {
return false;
}
});
El control de envío de formularios del lado del cliente se puede lograr con bastante elegancia haciendo que el controlador onsubmit oculte el botón de envío y lo reemplace con una animación de carga. De esa manera, el usuario obtiene retroalimentación visual inmediata en el mismo lugar donde ocurrió su acción (el clic). Al mismo tiempo, evita que el formulario se envíe en otro momento.
Si envía el formulario a través de XHR, tenga en cuenta que también debe manejar los errores de envío, por ejemplo, un tiempo de espera. Debería volver a mostrar el botón de envío porque el usuario debe volver enviar el formulario.
En otra nota, llimllib trae un punto muy válido. Toda la validación del formulario debe ocurrir en el servidor. Esto incluye múltiples comprobaciones de envío. ¡Nunca confíes en el cliente! Este no es solo un caso si JavaScript está desactivado. Debe tener en cuenta que todo el código del lado del cliente se puede modificar. Es algo difícil de imaginar, pero el html / javascript que habla con su servidor no es necesariamente el html / javascript que ha escrito.
Como sugiere llimllib, genere el formulario con un identificador que sea único para ese formulario y colóquelo en un campo de entrada oculto. Almacene ese identificador. Al recibir datos del formulario, solo procese cuando el identificador coincida. (También vincular el identificador a la sesión del usuario y hacer coincidir eso, también, para mayor seguridad). Después del procesamiento de datos, elimine el identificador.
Por supuesto, de vez en cuando, necesitaría limpiar los identificadores para los que nunca se envió ningún dato de formulario. Pero lo más probable es que su sitio web ya emplee algún tipo de mecanismo de "recolección de basura".
<form onsubmit="if(submitted) return false; submitted = true; return true">
<form onsubmit="return (typeof submitted == 'undefined') ? (submitted = true) : !submitted">
, o escribir var submitted = false;
en el punto correcto de la secuencia de comandos, para evitar el error siguiente: Uncaught ReferenceError: submitted is not defined
.
Esta es una forma sencilla de hacerlo:
<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>
Desactive el botón enviar poco después de hacer clic. Asegúrese de manejar las validaciones correctamente. También mantenga una página intermedia para todo el procesamiento o las operaciones de la base de datos y luego redirija a la página siguiente. Esto asegura que la actualización de la segunda página no realice otro procesamiento.
form page ---submits to---> form_submission_script.php ---after saving, redirects to---> form_thankyou.html
Hash la hora actual, conviértela en una entrada oculta en el formulario. En el lado del servidor, verifique el hash de cada envío de formulario; si ya recibió ese hash, entonces tiene un envío repetido.
editar: confiar en javascript no es una buena idea, por lo que todos pueden seguir votando esas ideas, pero algunos usuarios no lo tendrán habilitado. La respuesta correcta es no confiar en la entrada del usuario en el lado del servidor.
Usando JQuery puedes hacer:
$('input:submit').click( function() { this.disabled = true } );
Y
$('input:submit').keypress( function(e) {
if (e.which == 13) {
this.disabled = true
}
}
);
Sé que etiquetó su pregunta con 'javascript', pero aquí hay una solución que no depende en absoluto de javascript:
Es un patrón de aplicación web llamado PRG , y aquí hay un buen artículo que lo describe
Puede evitar el envío múltiple simplemente con:
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;
. Aún es posible realizar envíos dobles, pero es probable que haya menos.
La respuesta más simple a esta pregunta es: "A veces, cuando la respuesta es lenta, uno puede hacer clic en el botón enviar varias veces. ¿Cómo evitar que esto suceda?"
Simplemente desactive el botón de envío del formulario, como el siguiente código.
<form ... onsubmit="buttonName.disabled=true; return true;">
<input type="submit" name="buttonName" value="Submit">
</form>
Deshabilitará el botón enviar, en el primer clic para enviar. Además, si tiene algunas reglas de validación, funcionará bien. Espero que te ayude.
En el lado del cliente , debe deshabilitar el botón de envío una vez que el formulario se envía con código javascript como el método proporcionado por @vanstee y @chaos.
Pero existe un problema de retraso en la red o situación de inhabilitación de JavaScript en la que no debe confiar en JS para evitar que esto suceda.
Entonces, en el lado del servidor , debe verificar el envío repetido de los mismos clientes y omitir el repetido que parece un intento falso del usuario.
Puede probar el complemento jquery de 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;
}
})
La solución más simple y elegante para mí:
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>
Esto permite enviar cada 2 segundos. En caso de validación 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;
});
})
la mejor manera de evitar el envío de varios es simplemente pasar la identificación del botón en el método.
function DisableButton() {
document.getElementById("btnPostJob").disabled = true;
}
window.onbeforeunload = DisableButton;
Hacer esto usando javascript es un poco fácil. A continuación se muestra el código que proporcionará la funcionalidad deseada:
$('#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>
Las soluciones más simples son deshabilitar el botón al hacer clic y habilitarlo después de que se complete la operación. Para verificar una solución similar en jsfiddle:
[click here][1]
Y puede encontrar otra solución en esta respuesta .
Esto funciona muy bien para mí. Envía la granja y hace que el botón se desactive y después de 2 segundos active el botón.
<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);}
En ECMA6 Syntex
function submitLimit() {
submitBtn = document.getElementById('submit');
setTimeout(() => { submitBtn.setAttribute('disabled', 'disabled') }, 1);
setTimeout(() => { submitBtn.removeAttribute('disabled') }, 4000);}
Solo para agregar a las posibles respuestas sin omitir la validación de entrada del navegador
$( document ).ready(function() {
$('.btn-submit').on('click', function() {
if(this.form.checkValidity()) {
$(this).attr("disabled", "disabled");
$(this).val("Submitting...");
this.form.submit();
}
});
});
Una alternativa a lo propuesto anteriormente es:
jQuery('form').submit(function(){
$(this).find(':submit').attr( 'disabled','disabled' );
//the rest of your code
});