Как предотвратить повторное заполнение формы при обновлении страницы (F5/CTRL + R)
У меня есть простая форма, которая отправляет текст в мою таблицу SQL. Проблема в том, что после того, как пользователь отправит текст, они могут обновить страницу, и данные будут отправлены снова, не заполнив форму снова. Я мог перенаправить пользователя на другую страницу после отправки текста, но хочу, чтобы пользователи оставались на одной странице.
Я помню, что читал кое-что о том, чтобы дать каждому пользователю уникальный идентификатор сеанса и сравнить его с другим значением, которое разрешило проблему, которую я имею, но я забыл, где она находится.
Ответы
Ответ 1
Используйте шаблон Post/Redirect/Get. http://en.wikipedia.org/wiki/Post/Redirect/Get
На моем веб-сайте я сохраню сообщение в cookie или сеансе, перенаправляю после публикации, читаю cookie/session и затем очищаю значение этой сессии или переменной cookie.
Ответ 2
Вам действительно нужно использовать шаблон Post Redirect Get для обработки этого, но если вы каким-то образом оказались в позиции, где PRG не является жизнеспособным (например, сама форма включена, предотвращая переадресацию), вы можете использовать некоторые из параметры запроса для создания строки на основе содержимого, а затем убедитесь, что вы еще не отправили ее.
//create digest of the form submission:
$messageIdent = md5($_POST['name'] . $_POST['email'] . $_POST['phone'] . $_POST['comment']);
//and check it against the stored value:
$sessionMessageIdent = isset($_SESSION['messageIdent'])?$_SESSION['messageIdent']:'';
if($messageIdent!=$sessionMessageIdent){//if its different:
//save the session var:
$_SESSION['messageIdent'] = $messageIdent;
//and...
do_your_thang();
} else {
//you've sent this already!
}
Ответ 3
-
Используйте заголовок и перенаправляйте страницу.
header("Location:your_page.php");
Вы можете перенаправить на ту же страницу или на другую страницу.
-
Unset $_POST после вставки его в базу данных.
unset($_POST);
Ответ 4
Когда форма обрабатывается, вы перенаправляетесь на другую страницу:
... process complete....
header('Location: thankyou.php');
вы также можете перенаправить на ту же страницу.
если вы делаете что-то вроде комментариев и хотите, чтобы пользователь оставался на одной странице, вы можете использовать Ajax для обработки отправки формы
Ответ 5
Довольно верный способ - реализовать уникальный идентификатор в сообщении и кэшировать его в
<input type='hidden' name='post_id' value='".createPassword(64)."'>
Затем в коде выполните следующее:
if( ($_SESSION['post_id'] != $_POST['post_id']) )
{
$_SESSION['post_id'] = $_POST['post_id'];
//do post stuff
} else {
//normal display
}
function createPassword($length)
{
$chars = "abcdefghijkmnopqrstuvwxyz023456789";
srand((double)microtime()*1000000);
$i = 0;
$pass = '' ;
while ($i <= ($length - 1)) {
$num = rand() % 33;
$tmp = substr($chars, $num, 1);
$pass = $pass . $tmp;
$i++;
}
return $pass;
}
Ответ 6
вы можете использовать форму повторной отправки через переменную сеанса Как
сначала вам нужно установить rand() в текстовое поле и $_SESSION ['rand'] на странице формы
<form action="" method="post">
<?php
$rand=rand();
$_SESSION['rand']=$rand;
?>
<input type="hidden" value="<?php echo $rand; ?>" name="randcheck" />
Your Form Other Field
<input type="submit" name="submitbtn" value="submit" />
</form>
После проверки $_SESSION ['rand'] с текстовым полем $_POST ['randcheck'] значение
Как
if(isset($_POST['submitbtn']) && $_POST['randcheck']==$_SESSION['rand'])
{
//Your Code here
}
Ответ 7
Просто переадресовывайте его на ту же страницу после использования данных формы, и он работает. Я пробовал это.
header('location:yourpage.php');
Ответ 8
Утонченная версия сообщения Moob. Создайте хэш POST, сохраните его как файл cookie сеанса и сравните хеширования каждого сеанса.
// Optionally Disable browser caching on "Back"
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Expires: Sun, 1 Jan 2000 12:00:00 GMT' );
header( 'Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT' );
$post_hash = md5( json_encode( $_POST ) );
if( session_start() )
{
$post_resubmitted = isset( $_SESSION[ 'post_hash' ] ) && $_SESSION[ 'post_hash' ] == $post_hash;
$_SESSION[ 'post_hash' ] = $post_hash;
session_write_close();
}
else
{
$post_resubmitted = false;
}
if ( $post_resubmitted ) {
// POST was resubmitted
}
else
{
// POST was submitted normally
}
Ответ 9
После вставки его в базу данных вызовите метод unset(), чтобы очистить данные.
снята с охраны ($ _ POST);
Чтобы предотвратить обновление данных обновления, выполните перенаправление страницы на ту же страницу или на другую страницу после записи.
заголовок ( 'Location:'. $_ SERVER [ 'PHP_SELF']);
Ответ 10
В принципе, вам нужно перенаправить с этой страницы, но она все еще может стать проблемой, пока ваш интернет медленный (переадресация заголовка с сервера)
Пример базового сценария:
Нажмите кнопку отправки дважды
Способ решения
-
Клиентская сторона
- Отключить кнопку отправки, когда клиент кликнет по ней.
- Если вы используете JQuery: Jquery.one
- Шаблон PRG
-
Серверная сторона
- Использование дифференцированной временной отметки времени хэширования/метки времени при отправке запроса.
- Символы Userequest. Когда основные нагрузки назначают временный запрос, который, если повторяется, игнорируется.
Ответ 11
Я нашел следующее обходное решение. Вы можете избежать перенаправления после обработки запроса POST
, манипулируя history
объектом.
Итак, у вас есть HTML-форма:
<form method=POST action='/process.php'>
<input type=submit value=OK>
</form>
Когда вы обрабатываете эту форму на своем сервере, вы вместо перенаправления пользователя на /the/result/page
настраиваете заголовок Location
следующим образом:
$cat process.php
<?php
process POST data here
...
header('Location: /the/result/page');
exit();
?>
![введите описание изображения здесь]()
После обработки POST
ed данных вы выполняете небольшие <script>
и результат /the/result/page
<?php
process POST data here
render the <script> // see below
render `/the/result/page` // OK
?>
<script>
вы должны сделать:
<script>
window.onload = function() {
history.replaceState("", "", "/the/result/page");
}
</script>
Результат:
![введите описание изображения здесь]()
как вы можете видеть, данные формы POST
ed до process.php
script.
Этот script процесс POST
редактировать данные и рендеринг /the/result/page
сразу с помощью
- нет перенаправления
- no re
POST
данные при обновлении страницы (F5)
- no re
POST
при переходе к предыдущей/следующей странице через историю браузера
UPD
В качестве другого решения я прошу команду Mozilla FireFox, чтобы пользователи могли настроить заголовок NextPage
который будет работать как заголовок Location
и сделать шаблон post/redirect/get
устаревшим.
Короче. Когда серверный процесс успешно сформирует POST
данные:
- Настройка
NextPage
вместо Location
- Отобразить результат обработки данных формы
POST
, как это было бы сделать для запроса GET
в шаблоне post/redirect/get
В свою очередь браузер просматривает заголовок NextPage
:
- Откорректируйте
window.location
с NextPage
значением
- Когда пользователь обновляет страницу, браузер будет согласовывать
GET
запрос NextPage
вместо данных POST
формы
Я думаю, что это было бы отлично, если бы реализовано, не так ли? =)
Ответ 12
Я также хотел бы указать, что вы можете использовать подход javascript, window.history.replaceState
, чтобы предотвратить повторную отправку на кнопке обновления и возврата.
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>
Доказательство концепции здесь: https://dtbaker.net/files/prevent-post-resubmit.php
Я бы по-прежнему рекомендовал подход Post/Redirect/Get, но это новое решение JS.
Ответ 13
Использование шаблона Post/Redirect/Get из ответа Keverw - хорошая идея. Однако вы не можете оставаться на своей странице (и я думаю, что это было то, о чем вы просили?) Кроме того, иногда может fail
Если веб-пользователь обновляется до завершения первоначальной отправки из-за задержки сервера, что приводит к дублированию запроса HTTP POST в некоторые пользовательские агенты.
Другой вариант - сохранить в сеансе, если текст должен быть записан в вашу базу данных SQL следующим образом:
if($_SERVER['REQUEST_METHOD'] != 'POST')
{
$_SESSION['writeSQL'] = true;
}
else
{
if(isset($_SESSION['writeSQL']) && $_SESSION['writeSQL'])
{
$_SESSION['writeSQL'] = false;
/* save $_POST values into SQL */
}
}
Ответ 14
Как предотвратить повторное заполнение формы php без перенаправления. Если вы используете $_SESSION (после session_start) и форму $_POST, вы можете сделать что-то вроде этого:
if ( !empty($_SESSION['act']) && !empty($_POST['act']) && $_POST['act'] == $_SESSION['act'] ) {
// do your stuff, save data into database, etc
}
В вашей html-форме поставьте это:
<input type="hidden" id="act" name="act" value="<?php echo ( empty($_POST['act']) || $_POST['act']==2 )? 1 : 2; ?>">
<?php
if ( $_POST['act'] == $_SESSION['act'] ){
if ( empty( $_SESSION['act'] ) || $_SESSION['act'] == 2 ){
$_SESSION['act'] = 1;
} else {
$_SESSION['act'] = 2;
}
}
?>
Итак, каждый раз, когда форма отправляется, создается новый акт, сохраняется в сеансе и сравнивается с постулатом post.
Ps: если вы используете форму Get, вы можете легко изменить все POST с помощью GET, и он тоже работает.
Ответ 15
Как говорили другие, невозможно использовать post/redirect/get. Но в то же время довольно легко сделать то, что вы хотите сделать на стороне сервера.
На странице POST вы просто проверяете ввод пользователя, но не действуете на нем, вместо этого вы копируете его в массив SESSION. Затем вы снова перенаправляетесь на главную страницу представления. Ваша основная страница отправки начинается с проверки, существует ли массив SESSION, который вы используете, и если это необходимо скопировать в локальный массив и отключить его. Оттуда вы можете действовать на нем.
Таким образом, вы выполняете всю свою основную работу один раз, достигая того, что хотите.
Ответ 16
Почему бы просто не использовать переменную $_POST['submit']
в качестве логического оператора, чтобы сохранить все, что есть в форме. Вы всегда можете перенаправить на ту же страницу (в случае их обновления, и когда они попадут в go back
в браузере, переменная post post больше не будет установлена. Просто убедитесь, что ваша кнопка отправки имеет name
и id
of submit
.