Как предотвратить многократную отправку формы со стороны клиента? - PullRequest
85 голосов
/ 29 мая 2009

Иногда, когда ответ медленный, можно нажать кнопку отправки несколько раз.

Как предотвратить это?

Ответы [ 23 ]

92 голосов
/ 29 мая 2009

Используйте ненавязчивый JavaScript, чтобы отключить событие отправки в форме после того, как оно уже было отправлено. Вот пример использования jQuery.

РЕДАКТИРОВАТЬ: Исправлена ​​проблема с отправкой формы без нажатия кнопки отправки. Спасибо, ичибан.

$("body").on("submit", "form", function() {
    $(this).submit(function() {
        return false;
    });
    return true;
});
38 голосов
/ 17 октября 2012

Я попробовал решение vanstee вместе с ненавязчивой проверкой asp mvc 3, и если проверка клиента не удалась, код все еще выполняется, и отправка формы отключается навсегда. Я не могу повторно отправить после исправления полей. (см. комментарий Бджана)

Итак, я изменил скрипт Ванши так:

$("form").submit(function () {
    if ($(this).valid()) {
        $(this).submit(function () {
            return false;
        });
        return true;
    }
    else {
        return false;
    }
});
22 голосов
/ 30 мая 2009

Управление отправкой формы на стороне клиента может быть выполнено довольно элегантно, если обработчик onsubmit скрывает кнопку отправки и заменяет ее загрузочной анимацией. Таким образом, пользователь получает немедленную визуальную обратную связь в том же месте, где произошло его действие (щелчок). В то же время вы запрещаете отправку формы в другой раз.

Если вы отправляете форму через XHR, имейте в виду, что вы также должны обрабатывать ошибки отправки, например, тайм-аут. Вам нужно будет снова отобразить кнопку отправки, потому что пользователь должен повторно отправить форму.

С другой стороны, llimllib приводит очень верное замечание. Все проверки формы должны происходить на стороне сервера. Это включает в себя несколько проверок представления. Никогда не доверяйте клиенту! Это не только тот случай, если javascript отключен. Вы должны помнить, что весь код на стороне клиента может быть изменен. Это сложно представить, но html / javascript, общающийся с вашим сервером, не обязательно является написанным вами html / javascript.

Как предполагает llimllib, сгенерируйте форму с уникальным для этой формы идентификатором и поместите ее в скрытое поле ввода. Сохраните этот идентификатор. При получении данных формы обрабатывайте их только при совпадении идентификатора. (Также свяжите идентификатор с сеансом пользователя и сопоставьте его также для дополнительной безопасности.) После обработки данных удалите идентификатор.

Конечно, время от времени вам нужно очищать идентификаторы, для которых никогда не было отправлено никаких данных формы. Но, скорее всего, ваш сайт уже использует какой-то механизм «сборки мусора».

13 голосов
/ 29 мая 2009

Вот простой способ сделать это:

<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>
12 голосов
/ 29 мая 2009
<form onsubmit="if(submitted) return false; submitted = true; return true">
8 голосов
/ 29 мая 2009

Отключить кнопку отправки вскоре после щелчка. Убедитесь, что вы обрабатываете валидации правильно. Также сохраните промежуточную страницу для всех операций обработки или БД, а затем перенаправьте на следующую страницу. Это гарантирует, что обновление второй страницы не выполнит другую обработку.

5 голосов
/ 29 мая 2009

Используя JQuery, вы можете сделать:

$('input:submit').click( function() { this.disabled = true } );

&

   $('input:submit').keypress( function(e) {
     if (e.which == 13) {
        this.disabled = true 
     } 
    }
   );
5 голосов
/ 29 мая 2009

Вы также можете отобразить индикатор выполнения или счетчик, чтобы указать, что форма обрабатывается.

5 голосов
/ 29 мая 2009

Хешируйте текущее время, сделайте его скрытым вводом в форму. На стороне сервера проверьте хэш каждой отправки формы; если вы уже получили этот хэш, то у вас есть повторная отправка.

edit: полагаться на javascript не очень хорошая идея, поэтому вы все можете продолжать голосовать за эти идеи, но некоторые пользователи не смогут включить его Правильный ответ - не доверять пользовательскому вводу на стороне сервера.

4 голосов
/ 30 мая 2009

Я знаю, что вы пометили свой вопрос 'javascript', но вот решение, которое вообще не зависит от javascript:

Это шаблон веб-приложения с именем PRG , и вот хорошая статья , которая описывает его

...