Предотвращение двойного HTTP POST - PullRequest
19 голосов
/ 14 января 2009

Я сделал небольшое приложение для регистрации на событие. Пользователь вводит свои данные и нажимает кнопку «Войти».

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

Это распространенная проблема в Интернете, поскольку приложения для кредитных карт и форумы часто говорят: «Достаточно щелкнуть один раз!».

Полагаю, вы могли бы решить эту проблему, проверив те же данные, чтобы увидеть, является ли сообщение уникальным, но мне интересно, есть ли другие методы.

Этот курс не учитывается для веб-форм ASP.NET, поскольку POST не имеет большого значения.

Ответы [ 11 ]

22 голосов
/ 14 января 2009

Хотя решения JavaScript могут отключить кнопку отправки после ее нажатия, это не повлияет на тех людей, у которых отключен JavaScript. Вы должны всегда заставить вещи работать правильно без JavaScript, прежде чем добавлять его, иначе нет смысла, так как пользователи все равно смогут обойти проверки, просто отключив JavaScript.

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

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

20 голосов
/ 14 января 2009

Большинство ответов до сих пор были на стороне клиента. На стороне сервера вы можете создать скрытое поле с GUID при первом создании формы, а затем записать этот GUID как отправленную форму при получении сообщения. Проверьте это перед дальнейшей обработкой.

4 голосов
/ 14 января 2009

Решение на стороне пользователя - отключить кнопку отправки через Javascript после первого щелчка.

У него есть недостатки, но я вижу, что его часто используют на сайтах электронной коммерции.

Но это никогда не заменит настоящую проверку на стороне сервера.

3 голосов
/ 14 января 2009

Клиентского решения будет недостаточно, как указано во многих ответах здесь. Вам необходимо использовать отказоустойчивость на стороне сервера.

Часто игнорируемая причина, по которой отключение кнопки отправки не работает, заключается в том, что пользователь может просто обновить цель отправки (и нажать кнопку ОК в диалоговом окне «Вы уверены, что хотите повторно отправить данные POST?»). Или даже некоторые браузеры могут неявно перезагружать отправленную страницу, когда вы пытаетесь сохранить страницу на диск (например, вы пытаетесь сохранить печатную копию подтверждения заказа).

3 голосов
/ 14 января 2009

Методы на стороне клиента полезны, но вы можете связать их с некоторыми техниками на стороне сервера.

Одним из способов сделать это является включение в форму уникального токена (например, GUID или аналогичного), чтобы при обработке формы вы могли проверить, есть ли токен был использован, предотвращая двойную подачу.

В вашем случае, если у вас есть таблица с посетителями мероприятия, вы можете включить этот токен в столбец.

2 голосов
/ 20 сентября 2012

Всякий раз, когда страница запрашивается с сервера, создайте уникальный запрос request, сохраните его на стороне сервера, пометьте статус как НЕ обработано и передайте его вместе с текущей запрашиваемой страницей. Теперь, когда происходит отправка страницы, получите requestToken из «POST» -данных и проверьте статус и сохраните данные или выполните альтернативное действие.

В большинстве банковских приложений этот метод используется для предотвращения двойного «POST» ing. Так что это проверенный временем и надежный способ предотвращения двойных заявок.

1 голос
/ 21 декабря 2017

Ни одно из решений не предназначено для сервера балансировки нагрузки.

Если у вас есть какой-то балансировщик нагрузки, отправка UUID (или любого другого уникального номера) на сервер для сохранения и повторного чтения не будет работать хорошо, если сервер не знает о других серверах, поскольку каждый запрос может быть обработан другой сервер в среде без состояния. Эти серверы должны читать / писать в одном и том же месте.

Если у вас несколько серверов, вам понадобится некоторый общий кеш (например, Redis) для серверов для чтения / записи уникального значения в одном месте (что может быть чрезмерным инженерным решением, но работает).

1 голос
/ 11 декабря 2009

Почти никто не отключил JS. Подумайте о кодировании своего сайта электронной коммерции для 70-летней женщины, которая дважды щелкает каждую ссылку и кнопку. Все, что вы хотите сделать, это добавить JavaScript, чтобы она не нажимала «Заказать сейчас» дважды. Да - проверьте это на стороне сервера, тоже «будьте осторожны» - но не кодируйте для этого случая. Но ради лучшего пользовательского интерфейса сделайте это и на стороне клиента.

Вот несколько скриптов, которые я нашел:

//
// prevent double-click on submit
//
  jQuery('input[type=submit]').click(function(){
    if(jQuery.data(this, 'clicked')){
      return false;
    }
    else{
      jQuery.data(this, 'clicked', true);
      return true;
    }
  });

и

// Find ALL <form> tags on your page
$('form').submit(function(){
    // On submit disable its submit button
    $('input[type=submit]', this).attr('disabled', 'disabled');
});
0 голосов
/ 14 января 2009

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

0 голосов
/ 14 января 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...