Лучший способ избежать отправки из-за обновления страницы

Я думаю, что эта проблема часто возникает в веб-приложении. Но я подробно расскажу о своих проблемах.

Я хотел бы знать, как избавиться от этого поведения, например, когда у меня есть такой код:

<? if (isset($_POST['name'])) { ... operation on database, like to insert $_POST['name'] in a table ... echo "Operation Done"; die(); } ?> <form action='page.php' method='post' name="myForm"> <input type="text" maxlength="50" name="name" class="input400" /> <input type="submit" name="Submit" /> </form> 

Когда я отправляю форму, я вставляю данные в базу данных, и получаю сообщение Operation Done . Затем, если я обновляю страницу, данные снова будут загружены.

Как я могу избежать этой ситуации? Любые предложения будут хорошими 🙂

Не показывать ответ после вашего действия; перенаправлять на другую страницу после завершения действия. Если кто-то обновляется, они обновляют запрашиваемую страницу GET, на которую вы перенаправили.

 // submit // set success flash message (you are using a framework, right?) header('Location: /path/to/record'); exit; 

Установите случайное число в сеансе, когда отображается форма, а также поместите это число в скрытое поле. Если номер и номер сеанса совпадают, удалите сеанс, запустите запрос; если они этого не делают, повторно отобразите форму и создайте новый номер сеанса. Это основная идея токенов XSRF, вы можете больше узнать о них и их использование для обеспечения безопасности здесь: http://en.wikipedia.org/wiki/Cross-site_request_forgery

Вот пример:

 <?php session_start(); if (isset($_POST['formid']) && isset($_SESSION['formid']) && $_POST["formid"] == $_SESSION["formid"]) { $_SESSION["formid"] = ''; echo 'Process form'; } else { $_SESSION["formid"] = md5(rand(0,10000000)); ?> <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post"> <input type="hidden" name="formid" value="<?php echo htmlspecialchars($_SESSION["formid"]); ?>" /> <input type="submit" name="submit" /> </form> <?php } ?> 

Как это:

 <?php if(isset($_POST['uniqid']) AND $_POST['uniqid'] == $_SESSION['uniqid']){ // can't submit again } else{ // submit! $_SESSION['uniqid'] = $_POST['uniqid']; } ?> <form action="page.php" method="post" name="myForm"> <input type="hidden" name="uniqid" value="<?php echo uniqid();?>" /> <!-- the rest of the fields here --> </form> 

Я думаю, что это проще,

page.php

 <?php session_start(); if (isset($_POST['name'])) { ... operation on database, like to insert $_POST['name'] in a table ... $_SESSION["message"]="Operation Done"; header("Location:page.php"); exit; } ?> <html> <body> <div style='some styles'> <?php //message here echo $_SESSION["message"]; ?> </div> <form action='page.php' method='post'> <!--elements--> </form> </body> </html> 

Я рассматривал использование переменных сеанса, как это предлагали другие, но это может быть болью, когда переменная сеанса очищается из-за таймаута. Затем в моем приложении мне пришло, что для моих целей было гораздо более простое решение. Избавьтесь от проблемы, а не проверяйте ее. Решение ниже, как правило, работает для меня, потому что я вообще обрабатываю весь свой php, прежде чем сбрасывать его в свой <html> … </ html>.

 <?php // PROCESS STUFF FOR YOUR PAGE HOWEVER YOU LIKE // SAVE BACKUP COPIES OF _REQEUST _POST & _GET VARS IF NECESSARY FOR SOME REASON $SAVED_REQUEST = $_REQEUST; $SAVED_POST = $_POST; $SAVED_GET = $_GET; // FINALLY, IN YOUR LAST LINE ERASE THE PROBLEM VARIABLES... $_REQUEST = $_POST = $_GET = NULL; ?> <html> <!-- PUT YOUR HTML HERE, ECHOING VARIABLES THAT WERE PROCESSES ABOVE --> </html> 

Это работает только потому, что я обычно стараюсь отделить свой php от моего html как можно больше. Очевидно, что он не может быть полностью разделен, но «разделение» делает мое решение возможным и упрощает чтение обоих php, поскольку все это в одном месте, и это упрощает чтение HTML-кода, потому что это не так как разбито с кодом. Я думаю, вы могли бы теоретически просто поставить следующее в конце своей страницы.

 <?php $_REQUEST = $_POST = $_GET = NULL; ?> 

Итак, за то, что мне нужно, это то, что работает.

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

Благодаря тем, кто опубликовал их решение, которое быстро привело меня к себе.

 <?php //Check if there was a post if ($_POST) { //Assuming there was a post, was it identical as the last time? if (isset($_SESSION['pastData']) AND $_SESSION['pastData'] != $_POST) { //No, Save } else { //Yes, Don't save } } else { //Save } //Set the session to the most current post. $_session['pastData'] = $_POST; ?> 

Мы работаем над веб-приложениями, где мы проектируем количество php-форм. Это чертовски написать другую страницу, чтобы получить данные и отправить их для каждой формы. Чтобы избежать повторного представления, в каждой таблице мы создали поле «random_check», которое помечено как «Уникальное».

При загрузке страницы генерируется случайное значение и сохраняется в текстовом поле (которое явно скрыто).

В SUBMIT сохраните это случайное текстовое значение в поле «random_check» в вашей таблице. В случае запроса повторной отправки через ошибку, поскольку он не может вставить дублирующее значение.

После этого вы можете отобразить ошибку, как

 if ( !$result ) { die( '<script>alertify.alert("Error while saving data OR you are resubmitting the form.");</script>' ); } 

Нет необходимости перенаправлять …

заменить die(); с

 isset(! $_POST['name']); 

, устанавливая значение isset isset не равным $ _POST ['name'], поэтому при его обновлении он больше не будет добавляться в вашу базу данных, если вы еще не нажмете кнопку отправки.

 <? if (isset($_POST['name'])) { ... operation on database, like to insert $_POST['name'] in a table ... echo "Operation Done"; isset(! $_POST['name']); } ?> <form action='page.php' method='post' name="myForm"> <input type="text" maxlength="50" name="name" class="input400" /> <input type="submit" name="Submit" /> </form> 

Это происходит из-за простого обновления, он снова отправит ваш запрос.

Поэтому идея решить эту проблему, вылечив ее корень причины.

Я имею в виду, что мы можем настроить одну переменную сеанса внутри формы и проверить ее при обновлении.

 if($_SESSION["csrf_token"] == $_POST['csrf_token'] ) { // submit data } //inside from $_SESSION["csrf_token"] = md5(rand(0,10000000)).time(); <input type="hidden" name="csrf_token" value=" htmlspecialchars($_SESSION["csrf_token"]);">