У меня есть простая форма, которая отправляет текст в мою таблицу SQL. Проблема в том, что после того, как пользователь отправит текст, они могут обновить страницу, и данные будут отправлены снова, не заполнив форму снова. Я мог перенаправить пользователя на другую страницу после отправки текста, но я хочу, чтобы пользователи оставались на одной странице.
Я помню, что читал что-то о том, чтобы дать каждому пользователю уникальный идентификатор сеанса и сравнить его с другим значением, которое решило проблему, которую я имею, но я забыл, где она.
Используйте шаблон Post / Redirect / Get. http://en.wikipedia.org/wiki/Post/Redirect/Get
На моем веб-сайте я буду хранить сообщение в cookie или сеансе, перенаправить после публикации, прочитать cookie / session, а затем очистить значение этой сессии или переменной cookie.
Вы действительно должны использовать шаблон 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! }
Используйте заголовок и перенаправляйте страницу.
header("Location:your_page.php");
Вы можете перенаправить на ту же страницу или на другую страницу.
Unset $ _POST после вставки его в базу данных.
unset($_POST);
Когда форма обрабатывается, вы перенаправляетесь на другую страницу:
... process complete.... header('Location: thankyou.php');
вы также можете перенаправить на ту же страницу.
если вы делаете что-то вроде комментариев и хотите, чтобы пользователь оставался на одной странице, вы можете использовать Ajax для обработки формы
Довольно верный способ – реализовать уникальный идентификатор в сообщении и кэшировать его в
<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; }
вы можете использовать форму повторной отправки через переменную сеанса.
сначала вам нужно установить rand () в текстовое поле и $ _SESSION ['rand'] на странице формы
<form action="" method="post"> <?php $rand=rand(); $_SESSION['rand']=$rand; ?> <input type="hidden" value="<?php echo $rand; ?>" name="randcheck" /> Your Form's Other Field <input type="submit" name="submitbtn" value="submit" /> </form>
После проверки $ _SESSION ['rand'] с текстовым полем $ _POST ['randcheck'] value Like
if(isset($_POST['submitbtn']) && $_POST['randcheck']==$_SESSION['rand']) { //Your Code here }
Просто переадресовывайте его на ту же страницу после использования данных формы, и он работает. Я попробовал.
header('location:yourpage.php');
Утонченная версия сообщения Моба. Создайте хэш 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 MYH: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 }
Вставив его в базу данных, вызовите метод unset (), чтобы очистить данные.
снята с охраны ($ _ POST);
Чтобы предотвратить обновление данных обновления, выполните перенаправление страницы на ту же страницу или на другую страницу после вставки записи.
Заголовок ( 'Location:'. $ _ SERVER [ 'PHP_SELF']);
Я нашел следующее обходное решение. Вы можете избежать перенаправления после обработки запроса 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
данных вы выполняете небольшие <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
.
Этот скрипт обрабатывает POST
данные и рендеринг /the/result/page
сразу :
POST
данных при обновлении страницы (F5) POST
при переходе на предыдущую / следующую страницу через историю браузера UPD
В качестве другого решения я попрошу функцию запросить команду Mozilla FireFox, чтобы разрешить пользователям настраивать заголовок NextPage
который будет работать как заголовок Location
и сделать post/redirect/get
шаблон устаревшим.
Вкратце. Когда серверный процесс успешно формирует данные POST
он:
NextPage
вместо Location
POST
который будет отображать для запроса GET
в post/redirect/get
pattern Браузер, в свою очередь, видит заголовок NextPage
:
window.location
со значением NextPage
GET
с NextPage
вместо данных формы POST
Я думаю, что это было бы превосходно, если бы реализовано, не так ли? =)
Я также хотел бы указать, что вы можете использовать подход javascript, window.history.replaceState
чтобы предотвратить повторную 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.
Использование шаблона Post / Redirect / Get из ответа Keverw – хорошая идея. Тем не менее, вы не можете оставаться на своей странице (и я думаю, что это было то, о чем вы просили?) Кроме того, это может иногда терпеть неудачу :
Если веб-пользователь обновляется до того, как первоначальная подача завершилась из-за задержки сервера, в результате возникает дублированный запрос 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 */ } }
Как предотвратить повторную отправку 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; } } ?>
Таким образом, каждый раз при отправке формы создается новый акт, хранящийся в сеансе и сравниваемый с постулированием.
Ps: если вы используете форму Get, вы можете легко изменить все POST с помощью GET, и он тоже работает.
Как говорили другие, невозможно использовать post / redirect / get. Но в то же время довольно легко сделать то, что вы хотите сделать на стороне сервера.
На странице POST вы просто проверяете ввод пользователя, но не действуете на нем, вместо этого вы копируете его в массив SESSION. Затем вы снова перенаправляетесь на главную страницу представления. Ваша основная страница отправки начинается с проверки, существует ли массив SESSION, который вы используете, и если это необходимо скопировать в локальный массив и отключить его. Оттуда вы можете действовать на нем.
Таким образом, вы выполняете всю свою основную работу один раз, достигая того, что хотите.
Почему бы просто не использовать переменную $_POST['submit']
как логическую инструкцию, чтобы сохранить все, что есть в форме. Вы всегда можете перенаправить на ту же страницу (в случае их обновления, а когда они удастся go back
в браузере, переменная post post больше не будет установлена. Просто убедитесь, что ваша кнопка отправки имеет name
и id
submit
.