Czasami, gdy odpowiedź jest powolna, można wielokrotnie kliknąć przycisk przesyłania.
Jak temu zapobiec?
Czasami, gdy odpowiedź jest powolna, można wielokrotnie kliknąć przycisk przesyłania.
Jak temu zapobiec?
Odpowiedzi:
Użyj dyskretnego javascript, aby wyłączyć zdarzenie przesyłania w formularzu po jego już przesłaniu. Oto przykład użycia jQuery.
EDYCJA: Naprawiono problem z przesyłaniem formularza bez klikania przycisku przesyłania. Dzięki, ichibanie.
$("body").on("submit", "form", function() {
$(this).submit(function() {
return false;
});
return true;
});
return true
? Myślę, że pierwsze zgłoszenie powinno działać bez tego.
return true
jest to domniemane, jeśli zostanie pominięte.
$(this).find("input[type='submit']").attr('disabled', 'disabled').val('submiting'); return true; });
Wypróbowałem rozwiązanie Vanstee wraz z dyskretną walidacją asp mvc 3, a jeśli walidacja klienta się nie powiedzie, kod jest nadal uruchamiany, a przesyłanie formularzy jest wyłączone na dobre. Nie mogę przesłać ponownie po poprawieniu pól. (patrz komentarz bjan)
Więc zmodyfikowałem skrypt vanstee w ten sposób:
$("form").submit(function () {
if ($(this).valid()) {
$(this).submit(function () {
return false;
});
return true;
}
else {
return false;
}
});
Kontrolę przesyłania formularzy po stronie klienta można osiągnąć całkiem elegancko, jeśli program obsługi onsubmit ukryje przycisk przesyłania i zastąpi go animacją ładowania. W ten sposób użytkownik otrzymuje natychmiastową wizualną informację zwrotną w tym samym miejscu, w którym miało miejsce jego działanie (kliknięcie). Jednocześnie uniemożliwiasz przesłanie formularza innym razem.
Jeśli przesyłasz formularz przez XHR, pamiętaj, że musisz również zająć się błędami przesyłania, na przykład przekroczeniem limitu czasu. Musiałbyś ponownie wyświetlić przycisk przesyłania, ponieważ użytkownik musi ponownie przesłać formularz.
Z drugiej strony llimllib przedstawia bardzo ważny punkt. Cała weryfikacja formularza musi odbywać się po stronie serwera. Obejmuje to wielokrotne sprawdzanie przedłożenia. Nigdy nie ufaj klientowi! Dzieje się tak nie tylko w przypadku wyłączenia javascript. Należy pamiętać, że cały kod po stronie klienta można modyfikować. Trudno to sobie wyobrazić, ale html / javascript komunikujący się z serwerem niekoniecznie musi być napisanym przez Ciebie html / javascript.
Jak sugeruje llimllib, wygeneruj formularz z identyfikatorem, który jest unikalny dla tego formularza i umieść go w ukrytym polu wejściowym. Przechowuj ten identyfikator. Podczas otrzymywania danych formularza przetwarzaj je tylko wtedy, gdy identyfikator jest zgodny. (Również łączenie identyfikatora z sesją użytkownika i dopasowywanie go również dla dodatkowego bezpieczeństwa). Po przetworzeniu danych usuń identyfikator.
Oczywiście od czasu do czasu musiałbyś wyczyścić identyfikatory, dla których nigdy nie przesłano żadnych danych formularza. Ale najprawdopodobniej Twoja witryna już wykorzystuje jakiś mechanizm „zbierania śmieci”.
<form onsubmit="if(submitted) return false; submitted = true; return true">
<form onsubmit="return (typeof submitted == 'undefined') ? (submitted = true) : !submitted">
lub zapisu var submitted = false;
w odpowiednim momencie swojego skryptu, aby uniknąć następujący błąd: Uncaught ReferenceError: submitted is not defined
.
Oto prosty sposób, aby to zrobić:
<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>
Wyłącz przycisk przesyłania wkrótce po kliknięciu. Upewnij się, że poprawnie obsługujesz walidacje. Zachowaj również stronę pośrednią dla wszystkich operacji przetwarzania lub operacji DB, a następnie przekieruj do następnej strony. Daje to pewność, że odświeżenie drugiej strony nie spowoduje kolejnego przetwarzania.
form page ---submits to---> form_submission_script.php ---after saving, redirects to---> form_thankyou.html
Hasz bieżący czas, uczyń go ukrytym wejściem w formularzu. Po stronie serwera sprawdź hash każdego przesłanego formularza; jeśli już otrzymałeś ten hash, masz powtórne przesłanie.
edycja: poleganie na javascript nie jest dobrym pomysłem, więc wszyscy możecie dalej głosować za tymi pomysłami, ale niektórzy użytkownicy nie będą mieli włączonej opcji. Prawidłowa odpowiedź brzmi: nie ufaj wejściom użytkownika po stronie serwera.
Za pomocą JQuery możesz:
$('input:submit').click( function() { this.disabled = true } );
&
$('input:submit').keypress( function(e) {
if (e.which == 13) {
this.disabled = true
}
}
);
Wiem, że oznaczyłeś swoje pytanie tagiem „javascript”, ale oto rozwiązanie, które w ogóle nie zależy od javascript:
Jest to wzorzec aplikacji internetowej o nazwie PRG , a oto dobry artykuł, który go opisuje
Aby zapobiec wielokrotnemu przesyłaniu, wystarczy:
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;
. Podwójne przesyłanie jest nadal możliwe, ale prawdopodobnie jest ich mniej.
Najprostsza odpowiedź na to pytanie: „Czasami, gdy odpowiedź jest powolna, można kilka razy kliknąć przycisk przesyłania. Jak temu zapobiec?”
Po prostu wyłącz przycisk przesyłania formularza, jak w poniższym kodzie.
<form ... onsubmit="buttonName.disabled=true; return true;">
<input type="submit" name="buttonName" value="Submit">
</form>
Spowoduje to wyłączenie przycisku przesyłania po pierwszym kliknięciu w celu przesłania. Również jeśli masz jakieś reguły walidacji, to będzie działać dobrze. Mam nadzieję, że to pomoże.
Po stronie klienta należy wyłączyć przycisk przesyłania po przesłaniu formularza z kodem javascript, tak jak w przypadku metody dostarczonej przez @vanstee i @chaos.
Ale istnieje problem z opóźnieniem sieci lub sytuacją z wyłączoną obsługą javascript, w której nie powinieneś polegać na JS, aby temu zapobiec.
Tak więc po stronie serwera należy sprawdzić powtórne przesłanie od tych samych klientów i pominąć powtórzone, które wydaje się fałszywą próbą użytkownika.
Możesz wypróbować wtyczkę safeform jquery.
$('#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;
}
})
Najprostsze i eleganckie rozwiązanie dla mnie:
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>
Umożliwia to przesyłanie co 2 sekundy. W przypadku walidacji z przodu.
$(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;
});
})
Najlepszym sposobem na uniknięcie przesyłania wielokrotnych jest po prostu przekazanie identyfikatora przycisku w metodzie.
function DisableButton() {
document.getElementById("btnPostJob").disabled = true;
}
window.onbeforeunload = DisableButton;
Aby to zrobić za pomocą javascript jest trochę łatwe. Poniżej znajduje się kod, który zapewni pożądaną funkcjonalność:
$('#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>
Najprostszym rozwiązaniem jest wyłączenie przycisku po kliknięciu i włączenie go po zakończeniu operacji. Aby sprawdzić podobne rozwiązanie na jsfiddle:
[click here][1]
W tej odpowiedzi możesz znaleźć inne rozwiązanie .
U mnie to działa bardzo dobrze. Podaje farmę i wyłącza przycisk, a po 2 sekundach aktywuje przycisk.
<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);}
W ECMA6 Syntex
function submitLimit() {
submitBtn = document.getElementById('submit');
setTimeout(() => { submitBtn.setAttribute('disabled', 'disabled') }, 1);
setTimeout(() => { submitBtn.removeAttribute('disabled') }, 4000);}
Wystarczy dodać do możliwych odpowiedzi bez pomijania sprawdzania poprawności danych wejściowych przeglądarki
$( document ).ready(function() {
$('.btn-submit').on('click', function() {
if(this.form.checkValidity()) {
$(this).attr("disabled", "disabled");
$(this).val("Submitting...");
this.form.submit();
}
});
});
Alternatywą dla tego, co zaproponowano wcześniej, jest:
jQuery('form').submit(function(){
$(this).find(':submit').attr( 'disabled','disabled' );
//the rest of your code
});