Каковы некоторые методы предотвращения двойной публикации в форме? (PHP)

Я хочу, чтобы пользователи случайно не отправляли комментарий дважды. Я использую метод PRG (post redirect get), так что я вставляю данные на другую страницу, а затем перенаправляю пользователя на страницу с комментарием. Это позволяет пользователям обновляться столько раз, сколько они хотят. Однако это не работает, когда пользователь возвращается и нажимает кнопку «Отправить» снова или когда они нажимают «Отправить 100 раз очень быстро». Я не хочу 100 одинаковых комментариев.

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

//makerandomtoken(20) returns a random 20 length char. <form method="post" ... > <input type="text" id="comments" name="comments" class="commentbox" /><br/> <input type="hidden" name="_token" value="<?php echo $token=makerandomtoken(20); ?>" /> <input type="submit" value="submit" name="submit" /> </form> if (isset($_POST['submit']) && !empty($comments)) { $comments= mysqli_real_escape_string($dbc,trim($_POST['comments'])); //how do I make the if-statment to check if the token has been already set once? if ( ____________){ //don't insert comment because already clicked submit } else{ //insert the comment into the database } } 

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

МЕТОДЫ: кто-то предложил использовать сеансы. Я бы установил случайный токен на $ _SESSION ['_ token'] и проверить, равен ли этот токен сеансу $ _POST ['_ токен'], но как это сделать? Когда я попытался, он все еще не проверяет

Если вы хотите предотвратить двойное представление, вы должны сохранить состояние «отправлено» по сравнению с «не отправлено». У вас есть несколько вариантов, где хранить эту информацию.

  • База данных – добавьте скрытое поле с уникальным уникальным значением для автогенерации (вы можете создать короткую случайную строку и добавить текущее время). Это значение также может использоваться для идентификации разговора – если вам нужен веб-разговор с состоянием. Добавьте это значение в базу данных и сделайте его уникальным. Недостатки: избыточное хранилище в базе данных, снижение производительности на вставке комментариев, должны генерировать уникальную строку.
  • Сессия – добавьте одно и то же скрытое поле со значением, сгенерированным в аналогичном вопросе. Когда пользователь отправляет форму, сохраните значение в сеансе, если его еще нет. Если это так, это двойное подчинение. Недостатки: вам все равно нужно создать уникальный токен.
  • Браузер – (1) Добавьте некоторые javascript, чтобы отключить кнопку отправки после ее нажатия. (2) имеют скрытое поле, которое начинается со значения 0 и изменяется на 1, когда пользователь нажимает кнопку отправки. Если пользователь снова нажимает кнопку, вы проверяете, является ли значение 1 и прерывается, если оно есть. Преимущества: нет уникальной строки. Недостатки: требуется включить javascript; вы можете потребовать, чтобы строка в любом случае выполняла веб-беседы с состоянием.

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

  • Он останавливает публикацию пользователем одного и того же комментария в разных местах. Если это проблема, сохраните хэш комментария и идентификатор того, что он комментирует.
  • Пользователь может нажать «назад» и отправить другой комментарий. Я считаю эту функцию (это лучше, чем удаление комментария, поскольку оно соответствует случайному токену предыдущего комментария). Автоматически интерпретировать это как редактирование комментариев непросто.
  • Он не работает, если пользователь нажимает «отправить» на альтернативных вкладках. (Я считаю, что это маловероятно, и это не требует хранения нескольких случайных токенов.)

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

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

вы также можете сделать это в jquery, это очень просто.

 $(document).on('click', '.className', function(){ $(this).css( 'pointer-events', 'none' ); });