Я думаю, что эта проблема часто возникает в веб-приложении. Но я подробно расскажу о своих проблемах.
Я хотел бы знать, как избавиться от этого поведения, например, когда у меня есть такой код:
<? 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"]);">