Подтвердить что ты не робот

Как предотвратить множественную отправку форм при нескольких кликах в PHP

Как предотвратить множественную отправку формы несколькими кликами в PHP

4b9b3361

Ответ 1

Использовать уникальный токен, сгенерированный каждый раз при отображении формы и который может использоваться только один раз; полезно также предотвращать атаки CSRF и replay, Маленький пример:

<?php
session_start();

/**
 * Creates a token usable in a form
 * @return string
 */
function getToken(){
  $token = sha1(mt_rand());
  if(!isset($_SESSION['tokens'])){
    $_SESSION['tokens'] = array($token => 1);
  }
  else{
    $_SESSION['tokens'][$token] = 1;
  }
  return $token;
}

/**
 * Check if a token is valid. Removes it from the valid tokens list
 * @param string $token The token
 * @return bool
 */
function isTokenValid($token){
  if(!empty($_SESSION['tokens'][$token])){
    unset($_SESSION['tokens'][$token]);
    return true;
  }
  return false;
}

// Check if a form has been sent
$postedToken = filter_input(INPUT_POST, 'token');
if(!empty($postedToken)){
  if(isTokenValid($postedToken)){
    // Process form
  }
  else{
    // Do something about the error
  }
}

// Get a token for the form we're displaying
$token = getToken();
?>
<form method="post">
  <fieldset>
    <input type="hidden" name="token" value="<?php echo $token;?>"/>
    <!-- Add form content -->
  </fieldset>
</form>

Объедините его с перенаправлением, чтобы вы сохраняли идеальное поведение назад и вперед. Подробнее о перенаправлении см. В POST/redirect/GET.

Ответ 2

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

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

Это всего лишь один пример - вы можете использовать это как начало.

Ответ 3

Вы можете добавить что-то вроде этого

<input type="hidden" name="form-token" value="someRandomNumber">

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

В большинстве случаев отключенная форма делает трюк, например, отключив кнопку или добавив return false к событию отправки формы (не уверен, что это работает без jQuery, хотя).

Ответ 4

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

Ответ 5

Это самый коммонический ответ на вашу проблему.

if (isset($_COOKIE['FormSubmitted']))
{
    die('You may only submit this form once per session!');
}

Ответ 6

Можете ли вы просто скрыть кнопку при нажатии? Это не повлияло бы на обработку формы (поскольку я знаю, что проблема заключается в немедленном отключении кнопки), но она будет по существу делать то же самое. Если вы действительно беспокоитесь об этом, вы можете просто показать еще одну кнопку, которая на самом деле ничего не делает. Может быть, нетрадиционная работа, но, тем не менее, работа.