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

Иногда пользователь может дважды нажать Enter , и сообщение будет вставлено дважды.

Есть ли решение предотвратить это, кроме как проверить, есть ли сообщение с тем же title и content ?

Существует несколько решений этой проблемы:

  1. Используйте Javascript, чтобы отключить кнопку отправки формы при ее отправке. Недостатком этого является то, что это АБСОЛЮТНО не является надежным способом. Очень легко отправить формы без нажатия кнопки, и это также не сработает для пользователей с отключенным JavaScript. Я бы определенно не рекомендовал этот метод.

    Пример:

      
  2. Используйте сеансы PHP для установки переменной сеанса (например, $ _SESSION [‘posttimer’]) в текущую временную метку для сообщения. Прежде чем обрабатывать форму в PHP, проверьте, существует ли переменная $ _SESSION [‘posttimer’] и проверяет определенную временную разницу (IE: 2 секунды). Таким образом, вы можете легко отфильтровать двойные представления.

    Пример:

     // form.html 
    // foo.php if (isset($_POST) && !empty($_POST)) { if (isset($_SESSION['posttimer'])) { if ( (time() - $_SESSION['posttimer']) < = 2) { // less then 2 seconds since last post } else { // more than 2 seconds since last post } } $_SESSION['posttimer'] = time(); }
  3. Включите уникальный токен в каждом POST. В этом случае вы также должны установить переменную сеанса в токен, который хотите включить, а затем отобразить токен в форме. После отправки формы вы повторно создаете токен. Когда поданный токен не совпадает с токеном в вашей сессии, форма была повторно отправлена ​​и должна быть объявлена ​​недействительной.

    Пример:

     // form.php < ?php // obviously this can be anything you want, as long as it is unique $_SESSION['token'] = md5(session_id() . time()); ?> 
    // foo.php if (isset($_SESSION['token'])) { if (isset($_POST['token'])) { if ($_POST['token'] != $_SESSION['token']) { // double submit } } }

Используйте уникальный токен с сообщением, чтобы каждый пост / postback обрабатывался только один раз.

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

Создайте уникальный одноразовый ключ для отправки с помощью формы.

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

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

Предотrotation повторной подачи формы показывает способ сделать это без javascript.

Отключите кнопку отправки с помощью Javascript после отправки формы ( onsubmit ).

Обратите внимание: если пользователь отключил Javascript, он все равно может отправить два раза. Является ли это достаточно часто, чтобы оправдать и проверку вашего кода (как вы сказали в своем вопросе), зависит от вас.

В качестве альтернативы используйте одноразовые ключи формы.

Я использую это:

 $form_token = $_SESSION['form_token'] = md5(uniqid()); 

отправьте $ form_token с формой, затем …

Я проверяю form_token:

 if($_SESSION['form_token'] != $_POST['form_token']) { echo 'Error'; } 

отключите кнопку отправки, как только пользователь отправит форму, используя JavaScript. Это то, что, например, StackOverflow использует, когда вы отвечаете на вопрос.

Например

  

Нажатие кнопки submit в два раза редко приводит к нескольким вставкам, но если вы хотите получить мертвое простое решение, используйте

 onsubmit="document.getElementById('submit').disabled = true" 

в теге формы, при условии, что вы передадите свою кнопку отправки id="submit"

Используйте JavaScript, чтобы отключить кнопку, как только она будет нажата.

 onclick="this.disabled=true;forms[0].submit();" 

Другой способ создать страницу подтверждения, где пользователь может, наконец, нажать кнопку отправки. Это может уменьшить возможности такого рода.

Я делаю следующее на action.php

 if($_SESSION && isset($_SESSION['already_submitted'])) { # If already submitted just redirect to thank you page } else { # If first submit then assign session value and process the form $_SESSION['already_submitted'] = true; # Process form } 

Примечание. Всегда начинайте сеансы в заголовке с помощью session_start ();

Aron Rotteveel Включает в себя уникальный токен на каждом POST для меня. Однако моя форма по-прежнему отправляется, когда пользователь обновляет страницу (F5). Мне удалось решить эту проблему, добавив сброс:

  // reset session token $_SESSION['token'] = md5( $_POST['token'] . time() ); 

мои заключительные сценарии:

 if (isset($_SESSION['token'])) { if (isset($_POST['token'])) { if ($_POST['token'] != $_SESSION['token']) { echo '

Oops! You already submitted this request.

'; } else { // process form // reset session token $_SESSION['token'] = md5( $_POST['token'] . time() ); } } else { echo 'post token not set'; $_SESSION['token'] = md5( $somevariable . time() ); } }

ой! не забудьте добавить session_start(); перед < !DOCTYPE>

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

Используйте JavaScript, чтобы остановить его отправку