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

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

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

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

<?
    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. Затем, если я обновляю страницу, данные снова будут загружены.

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

4b9b3361

Ответ 1

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

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

Ответ 2

Задайте случайное число в сеансе, когда отображается форма, а также поместите это число в скрытое поле. Если номер и номер сеанса совпадают, удалите сеанс, запустите запрос; если они этого не делают, повторно отобразите форму и создайте новый номер сеанса. Это основная идея токенов 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 } ?>

Ответ 3

Вот так:

<?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>

Ответ 4

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

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>

Ответ 5

Я рассмотрел использование переменных сеанса, как предлагали другие, но может быть больно, когда переменная сеанса очищается из-за таймаута. Затем в моем приложении мне пришло, что для моих целей было гораздо более простое решение. Избавьтесь от проблемы, а не проверяйте ее. Решение ниже, как правило, работает для меня, потому что я обычно обрабатываю весь свой php, прежде чем сбрасывать его в my <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; ?>

Ответ 6

Итак, для чего мне нужно, это то, что работает.

Основываясь на всех вышеперечисленных решениях, это позволяет мне перейти от формы к другой форме и к форме 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;
?>

Ответ 7

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

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

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

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

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

Ответ 8

Не нужно перенаправлять...

замените 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>

Ответ 9

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

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

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

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"]);">