Предотвратить вставку повторяющихся записей при обновлении страницы вручную - PullRequest
2 голосов
/ 16 сентября 2010

У меня проблема, которая только что появилась.

Я работаю в среде MVC.Имена методов в моем классе интерфейса совпадают с именами модуля запроса и действия, т. Е. ?module=test&action=action приведет к появлению метода с именем public function test_action() { }

.Если проверка прошла успешно, создается запись, и я затем показываю шаблон другого модуля.Этот модуль ожидает серию переменных post, поскольку он используется в двух модулях.

Проблема, с которой я столкнулся, заключается в том, что, если пользователь успешно проходит проверку и пытается выполнить F5 страницу, создается другая новая записьи т.д.

Как я могу предотвратить это?

Обычно я бы перенаправлял заголовок после успешной вставки, но в этом случае я не могу.

Ответы [ 7 ]

5 голосов
/ 16 сентября 2010

Я бы сделал это совершенно по-другому. Я даже нахожу перенаправление неправильным способом обработки этого, поскольку изменение местоположения не предназначено для преодоления проблем логики / формы.

Правильное решение:

  • Добавление уникального хэша к вашей форме в виде скрытого ввода
  • Сохранить хэш в сеансе на стороне сервера
  • Когда форма отправляется, проверьте скрытый входной хеш с помощью хеша на вашем сервере
  • Выполнять вставку строки только тогда, когда форма проверяется правильно.

Если вы работаете с Zend Framework, для вас есть класс Zend_Form_Element_Hash.

2 голосов
/ 16 сентября 2010

Ошибка разработчика:

Вам нужно создать страницу обработчика, которая:

  • проверка отправленных данных
  • вставить строку
  • перенаправить пользователя
2 голосов
/ 16 сентября 2010

Вы можете / должны перенаправить на новую страницу после успешной вставки.

Поскольку вы работаете в MVC, вы можете добавить новый контроллер, который просто вызывает представление, которое вы хотите показать.

1 голос
/ 07 мая 2013

Вот что я делаю. Это работает для меня. Надеюсь, что это может помочь кому-то еще.

//+++ start token +++
//This is to prevent duplicate entry on page reload (F5). 19.   If I enter all values, press Record in journal and then press F5, the same values are recorded one more time. Need to prevent

// 3rd. $token_hash_from_input get value of input field name name="' .$_SESSION['token_hash'] .'"
$token_hash_from_input = $_SESSION['token_hash'];
//echo $token_hash_from_input .' token_hash_from_input<br>';
//echo $_POST[$token_hash_from_input] .' $_POST[$token_hash_from_input]<br>';
//var_dump($token_hash, $_POST);

// 4th. $_SESSION['token'] created/set in 1st. Then it as if goes around (at first to input field then after page reload returns here). However $_POST[$token_hash_from_input] is value received directly from input field. User click post and input field value is passed to $_POST[$token_hash_from_input]. Here I compare both.
if ( $_SESSION['token'] != htmlspecialchars($_POST[$token_hash_from_input]) ) {
$token_error .= 'yes';
//echo 'session token and token from input field are not the same <br> ';
}
else {
//echo 'session token is equal to post$token_hash)<br>';
}

// 1st. Create token and pass it to session
$token = sha1(uniqid(mt_rand(), true));
$_SESSION['token'] = $token;
//echo $_SESSION['token'] .' new $_SESSION[token]<br>';//after each page reload new token created. Then this token passed to input form (hidden field). value="' .$_SESSION['token'] .'"

// 2nd. Create token_hash and pass it to session. Token hash is to name input fields name and id. I may not use $token_hash and $_SESSION['token_hash']. Instead of this I can use name="token" and id="token".
$token_hash = sha1(uniqid($time_when_form_submitted .'token' .$_SERVER["REMOTE_ADDR"]));
//echo $token_hash .' $token_hash<br>';
$_SESSION['token_hash'] = $token_hash;
//echo $_SESSION['token_hash'] .' new SESSION$token_hash<br>';
// +++ end token +++

Поле ввода вот так

<input type="hidden" name="' .$_SESSION['token_hash'] .'" id="' .$_SESSION['token_hash'] .'" value="' .$_SESSION['token'] .'">

или

<input type="hidden" name="<?php echo $_SESSION['token_hash'] ?>" id="<?php echo $_SESSION['token_hash'] ?>" value="<?php echo $_SESSION['token'] ?>">

Полагаю, код можно улучшить (у меня нет хороших знаний php и т.д.)

0 голосов
/ 04 июля 2013

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

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

При событии загрузки страницы сохраните отметку даты / времени в переменной сеанса, при первой загрузке страницы переменная сеанса заполняется текущей датой./ время следующим образом:

* void Page_Load (Отправитель объекта, EventArgs e) {if (! IsPostBack) {Session ["update"] = Server.UrlEncode (System.DateTime.Now.ToString ());}} *

В событии PreRender страницы для переменной ViewState устанавливается значение переменной Session следующим образом:

void Page_PreRender(object obj,EventArgs e)
{
    ViewState["update"] = Session["update"];
}

Затем эти два значения сравниваются с каждымдругое непосредственно перед выполнением команды INSERT для базы данных.Если они равны, то команда может быть выполнена, а переменная Session обновляется с использованием текущей даты / времени, в противном случае команда игнорируется, как указано ниже:

void btnSubmit_Click(object obj, EventArgs e)
{
    string name = "";
    string qualification = "";


    if (Session["update"].ToString() == ViewState["update"].ToString())
    {
        if (txtName.Text != "" || txtName.Text != null)
        {
            name = txtName.Text.ToString();
        }

        if (txtQualification.Text != "" || txtQualification.Text != null)
        {
            qualification = txtQualification.Text.ToString();
        }

       //--- Insert data function should be execute here

       string strSql = "INSERT INTO Testdata (Name,Qualification) VALUES ('" + name + "','" + qualification + "')";

        SqlConnection ANConnection = new SqlConnection(ConnectionString);

        ANConnection.Open();
        SqlCommand ANCommand = new SqlCommand(strSql, ANConnection);
        ANCommand.ExecuteNonQuery();

        ANConnection.Close();
        ANConnection.Dispose();

        //--End of save data 

       lblMessage.Text = "Inserted Record Sucessfully 
       Session["update"] = Server.UrlEncode(System.DateTime.Now.ToString());
    }
    else
    {
        lblMessage.Text = "Failure – Due to Page Refresh";
        txtName.Text = "";
        txtQualification.Text = "";
    }
}
0 голосов
/ 16 сентября 2010

Если по какой-либо причине вы не можете перенаправить (что звучит странно), вы можете использовать «тот же» механизм проверки данных для сброса форм после успешной вставки.

Но это действительно ужасный путь.

0 голосов
/ 16 сентября 2010

"Обычно я бы перенаправил заголовок после успешной вставки, но в этом случае я не могу."

Вы сталкиваетесь с какой-то ошибкой в ​​этом?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...