Запретить кнопке «Назад» показывать предупреждение POST - PullRequest
39 голосов
/ 19 марта 2009

У меня есть приложение, которое предоставляет длинный список параметров для веб-страницы, поэтому я должен использовать POST вместо GET. Проблема в том, что когда страница отображается и пользователь нажимает кнопку «Назад», Firefox отображает предупреждение:

Чтобы отобразить эту страницу, Firefox должен отправить информацию, которая будет повторять любое действие (например, поиск или подтверждение заказа), которое было выполнено ранее.

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

По сути, я хотел бы сделать это так, как эта страница:

http://www.pikanya.net/testcache/

Введите что-то, отправьте и нажмите кнопку Назад. Без предупреждения, он просто возвращается.

Поиск в Google Я обнаружил, что это может быть ошибкой в ​​Firefox 3, но я бы хотел каким-то образом получить такое поведение даже после того, как они его "исправят".

Полагаю, это возможно с некоторыми заголовками HTTP, но какие именно?

Ответы [ 6 ]

37 голосов
/ 19 марта 2009

Смотрите мое золотое правило веб-программирования здесь:

Остановить вставку данных в базу данных дважды

Там написано: «Никогда не отвечайте телом на POST-запрос. Всегда выполняйте работу, а затем отвечайте заголовком Location: для перенаправления на обновленную страницу, чтобы браузер запрашивал ее с помощью GET ”

Если браузер когда-нибудь спросит пользователя о повторной отправке, ваше веб-приложение будет повреждено. Пользователь не должен видеть этот вопрос.

27 голосов
/ 19 марта 2009

Один из способов - перенаправить POST на страницу, которая перенаправляет на GET - см. Post / Redirect / Get on wikipedia .

Скажите, что ваш POST составляет 4 КБ данных формы. Предположительно, ваш сервер что-то делает с этими данными, а не просто отображает их один раз и выбрасывает, например, сохраняет их в базе данных. Продолжайте делать это, или, если это огромная форма поиска, создайте временную копию в базе данных, которая будет очищена через несколько дней, или на основе LRU, когда используется ограничение пространства. Теперь создайте представление данных, к которым можно получить доступ, используя GET. Если он временный, создайте для него идентификатор и используйте его в качестве URL; если это постоянный набор данных, он, вероятно, имеет идентификатор или что-то, что можно использовать для URL. В худшем случае алгоритм, подобный крошечному URL-адресу, может свернуть большой URL-адрес в гораздо меньший. Перенаправьте POST, чтобы получить представление данных.


Как историческая справка, эта техника была установившейся практикой в ​​1995 .

3 голосов
/ 19 марта 2009

Один из способов избежать этого предупреждения / поведения - это выполнить POST через AJAX, а затем отправить пользователя на другую страницу (или нет) отдельно.

2 голосов
/ 14 октября 2014

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

//If there's something in the POST, move it to the session and then redirect right back to where we are
if ($_POST) {
    $_SESSION['POST']=$_POST;
    redirect($_SERVER["REQUEST_URI"]);
}

//If there's something in the SESSION POST, move it back to the POST and clear the SESSION POST
if ($_SESSION['POST']) {
    $_POST=$_SESSION['POST'];
    unset($_SESSION['POST']);
}

Технически вам даже не нужно помещать его обратно в переменную с именем $ _POST. Но это помогает мне отслеживать, откуда и откуда поступили данные.

1 голос
/ 19 марта 2009

У меня есть приложение, которое выдает длинный список параметров на веб-страницу, поэтому я должен использовать POST вместо GET. Проблема в том, что когда страница отображается и пользователь нажимает кнопку «Назад», Firefox отображает предупреждение:

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

0 голосов
/ 12 ноября 2017

В качестве другого решения вы можете вообще отказаться от перенаправления.

Вы можете обработать и обработать результат обработки сразу, без POST подтверждающего предупреждения. Вам просто нужно манипулировать объектом истории браузера:

history.replaceState("", "", "/the/result/page")

См. полный или короткий ответы

...