Как предотвратить повторную отправку формы при обновлении страницы (F5 / CTRL + R)
У меня есть простая форма, которая отправляет текст в мою таблицу SQL. Проблема в том, что после того, как пользователь отправит текст, они могут обновить страницу, и данные будут отправлены снова, не заполнив форму снова. Я мог перенаправить пользователя на другую страницу после отправки текста, но хочу, чтобы пользователи оставались на одной странице. Я помню, что читал кое-что о том, чтобы дать каждому пользователю уникальный идентификатор сеанса и сравнить его с другим значением, которое разрешило проблему, которую я имею, но я забыл, где она находится.
@Adam: Adam: потому что это лишнее сделать еще один запрос к серверу, который, в свою очередь, будет снова получать некоторые данные из БД. Но это пустая трата ресурсов, потому что мы уже выбираем все необходимые данные при обработке запроса POST
@EugenKonkov в шаблоне PRG, вы просто перенаправили бы на страницу, которая показывает сообщение об успехе. Дальнейшая загрузка из БД не требуется.
@Adam: Вы также можете отобразить всю запись, созданную с помощью данных POST . В этом случае вам нужно SELECT его из БД. Например, когда вы создаете счет-фактуру, вы перенаправляетесь в /invoices/53 котором отображается весь счет, а не просто «успех».
16 ответов
На моем веб-сайте я сохраню сообщение в cookie или сеансе, перенаправляю после публикации, читаю cookie/session и затем очищаю значение этой сессии или переменной cookie.
Если вы используете шаблон PRG, то вы действительно покидаете страницу правильно? Не был ли вопрос, как заставить вещи работать, когда не перенаправлять?
Мне кажется, что если вы перенаправляете на ту же страницу, $ _POST очищается. Насколько я понимаю, это был желаемый эффект. Во всяком случае, это был МОЙ желаемый эффект. Я думаю, что ответ был бы лучше, если бы он сделал это явно.
Вам действительно нужно использовать шаблон 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! >
Спасибо, что поделились, но это не похоже на работу. Обновление страницы действительно повторно отправляет форму для меня. Возможно, я что-то упустил?
Обновление страницы приведет к повторной отправке всего, но мы выбираем только обработку данных отправки, если они отличаются от данных, отправленных в прошлый раз (которые мы храним в сеансе var ‘messageIdent’). Обрабатываете ли вы отправку формы в предложении «if messageIdents иначе» (т.е. где находится «do_your_thang ()»)?
Спасибо за ваш ответ. В итоге я просто реализовал шаблон Post / Redirect / Get, поэтому я не помню, что именно меня подвело. Еще раз спасибо за возвращение назад.
Этот метод не предназначен для блокировки повторной отправки . но для обнаружения повторной передачи, чтобы вы могли изменить свой код так, чтобы он не «делал» то, что вы делаете, если бы это была новая отправка. Другими словами: с помощью этого метода вы можете обнаружить «оригинальную» отправку и разместить ваши данные. Если это НЕ оригинально, не размещайте свои данные. Либо покажите предупреждение «попытка дублирования», либо, возможно, вместо «подтверждения».
Чтобы это работало, вы должны начать сеанс, добавив session_start(); в начале файла. w3schools.com/php/php_sessions.asp говорит, что Примечание: функция session_start () должна быть самой первой вещью в вашем документе. Перед любыми тегами HTML.
К сожалению, в PRG, когда пользователь открывает больше вкладок из одного сеанса, он может отправить Контент № 1 с первой вкладки и Контент № 2 со второй вкладки. Теперь в сеансе хранится только последний отправленный контент, поэтому Контент № 1 можно снова отправить с первой вкладки, а Контент № 2 снова со второй и т. Д. Таким образом, вы должны хранить хэш не только самого последнего содержимого, но и всех их, пока длится сеанс. Или вы можете удалить сохраненные хэши после периода допуска или, если их слишком много.
- Используйте заголовок и перенаправляйте страницу. header(«Location:your_page.php»); Вы можете перенаправить на ту же страницу или на другую страницу.
- Unset $_POST после вставки его в базу данных. unset($_POST);
Она не будет работать. Когда пользователь переходит на обратную страницу, он выполняет настройку переменных POST еще раз.
Когда форма обрабатывается, вы перенаправляетесь на другую страницу:
. process complete. header('Location: thankyou.php');
вы также можете перенаправить на ту же страницу.
если вы делаете что-то вроде комментариев и хотите, чтобы пользователь оставался на одной странице, вы можете использовать Ajax для обработки отправки формы
вы можете использовать форму повторной отправки через переменную сеанса Как
сначала вам нужно установить rand() в текстовое поле и $_SESSION [‘rand’] на странице формы
После проверки $_SESSION [‘rand’] с текстовым полем $_POST [‘randcheck’] значение Как
if(isset($_POST['submitbtn']) && $_POST['randcheck']==$_SESSION['rand']) < //Your Code here >
Да, мы можем использовать microtime () и time () также вместо rand (), любую функцию или переменную, которая дает другое значение, мы можем использовать. НО убедитесь, что вы установили это значение в переменную SESSION. здесь SESSION необходимо проверить с помощью поля randcheck и предотвратить повторную отправку формы.
Довольно верный способ — реализовать уникальный идентификатор в сообщении и кэшировать его в
Затем в коде выполните следующее:
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 return $pass; >
Я на самом деле просто написал что-то похожее на это, но не потрудился создать пароль, я просто перечислил свои формы (например: шаги 1-5), поэтому, если они равны, мы круто продолжаем, иначе не сохраняйте в БД и не отправляйте электронные письма. Но пусть пользователь приземлится, куда бы он его ни взял.
Я думаю, что это лучшее решение, чем перезагрузить страницу, так как я показываю сообщение, когда публикация удалась, и перезагрузка страницы удалит сообщение. это работает для меня, вы также можете использовать Uniqid
Просто переадресовывайте его на ту же страницу после использования данных формы, и он работает. Я пробовал это.
header('location:yourpage.php');
Это просто повторение того же ответа, который кто-то дал несколько лет назад. (На самом деле два других!)
Утонченная версия сообщения 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 >
Я нашел следующее обходное решение. Вы можете избежать перенаправления после обработки запроса POST , манипулируя history объектом.
Итак, у вас есть HTML-форма:
Когда вы обрабатываете эту форму на своем сервере, вы вместо перенаправления пользователя на /the/result/page настраиваете заголовок Location следующим образом:
После обработки POST ed данных вы выполняете небольшие и результат /the/result/page
// see below render `/the/result/page` // OK ?>
как вы можете видеть, данные формы POST ed до process.php script.
Этот script процесс POST редактировать данные и рендеринг /the/result/page сразу с помощью
- нет перенаправления
- no re POST данные при обновлении страницы (F5)
- no re POST при переходе к предыдущей/следующей странице через историю браузера
Короче. Когда серверный процесс успешно сформирует POST данные:
- Настройка NextPage вместо Location
- Отобразить результат обработки данных формы POST , как это было бы сделать для запроса GET в шаблоне post/redirect/get
В свою очередь браузер просматривает заголовок NextPage :
- Откорректируйте window.location с NextPage значением
- Когда пользователь обновляет страницу, браузер будет согласовывать GET запрос NextPage вместо данных POST формы
Я думаю, что это было бы отлично, если бы реализовано, не так ли? =)
В принципе, вам нужно перенаправить с этой страницы, но она все еще может стать проблемой, пока ваш интернет медленный (переадресация заголовка с сервера)
Нажмите кнопку отправки дважды
- Клиентская сторона
- Отключить кнопку отправки, когда клиент кликнет по ней.
- Если вы используете JQuery: Jquery.one
- Шаблон PRG
- Использование дифференцированной временной отметки времени хэширования/метки времени при отправке запроса.
- Символы Userequest. Когда основные нагрузки назначают временный запрос, который, если повторяется, игнорируется.
После вставки его в базу данных вызовите метод unset(), чтобы очистить данные.
снята с охраны ($ _ POST);
Чтобы предотвратить обновление данных обновления, выполните перенаправление страницы на ту же страницу или на другую страницу после записи.
заголовок ( ‘Location:’. $_ SERVER [ ‘PHP_SELF’]);
Я также хотел бы указать, что вы можете использовать подход javascript, window.history.replaceState , чтобы предотвратить повторную отправку на кнопке обновления и возврата.
if ( window.history.replaceState )
Я бы по-прежнему рекомендовал подход Post/Redirect/Get, но это новое решение JS.
Как говорили другие, невозможно использовать post/redirect/get. Но в то же время довольно легко сделать то, что вы хотите сделать на стороне сервера.
На странице POST вы просто проверяете ввод пользователя, но не действуете на нем, вместо этого вы копируете его в массив SESSION. Затем вы снова перенаправляетесь на главную страницу представления. Ваша основная страница отправки начинается с проверки, существует ли массив SESSION, который вы используете, и если это необходимо скопировать в локальный массив и отключить его. Оттуда вы можете действовать на нем.
Таким образом, вы выполняете всю свою основную работу один раз, достигая того, что хотите.
Как предотвратить повторное заполнение формы 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-форме поставьте это:
Итак, каждый раз, когда форма отправляется, создается новый акт, сохраняется в сеансе и сравнивается с постулатом post.
Ps: если вы используете форму Get, вы можете легко изменить все POST с помощью GET, и он тоже работает.
Как отправить форму в php, чтобы она не отправлялась повторно, после обновления страницы
Сегодня тема пойдет об отправке формы на html-страничке, чтобы, при повторном обновлении, она не отправлялась заново в БД.
Не знаю, было ли такое где-то на просторах интернета, но, когда я попыталась найти, а мне было жутко это нужно, причем очень срочно, то я столкнулась с кучей проблем.
Во первых, почти все источники предлагают делать это таким образом:
Но, проблема в нем следующая, если вы, уже где то в начале страницы отправили заголовки, то на вас будут ругаться, мол, «заголовки отправлены, зачем ты хочешь, чтобы я это сделал еще один раз, угомонись!»
1. обнулить форму
2. засунуть все переменные формы в переменную $_SESSION(нам нужно больше переменных сессии!)Но данные способы были неудобны, возможно, вам покажется, что это наоборот, самый лучший вариант и зачем изобретать велосипед?
Меня же, все способы, встретившиеся на просторах интернета, не устроили. И я решила сделать то, что будет удобно мне и не будет занимать большое количество переменных/времени/ресурсов.
Приступим.Для начала, создадим простенькую форму.
Затем добавим в форму метод отправки, действие и имя:
Действие будет происходить на другой странице, для удобства и дальнейшей функциональности.Затем, мы создаем файлик redir.php и работаем над ним:
/*redir.php*/ alert("Заполните все поля формы");'; > else < $name = $_POST["name"]; $phone = $_POST["phone"]; $datetime= date("l dS of F Y h:i:s A"); $mysqly=mysqli_query($connect,"INSERT INTO contacts VALUES ('','$name','$phone','$datetime','')") OR DIE (MYSQLI_ERROR());>> ?>
Все. Как видите это просто, быстро и удобно!
Надеюсь, вам пригодится данная статья.
Буду рада критике или вашим предложениям.
P.S. Да, можно сделать отправку заголовка на этой, дополнительной, странице, но, почему-то с использованием кода JS мне нравится больше.
P.P.S. Спасибо за ваше внимание.