POST-запрос местоположения, отправляющего заголовок Refresh, заставляет Firefox создавать GET-запрос, но при этом содержать данные POST - PullRequest
0 голосов
/ 03 сентября 2011

Рассмотрим следующий код; это в основном форма, которая отправляет некоторые данные через HTTP POST. Когда приходят данные POST, отправляется HTTP-заголовок Refresh.

<?php
if (!empty($_POST))
{
    header("Refresh: 5; URL=http://$_SERVER[SERVER_NAME]$_SERVER[REQUEST_URI]");
}
?>
<!doctype html>
<form method=post>
    <input type=hidden name=foo value=bar>
    <input type=submit>
</form>
<?php
echo "The location was requested using the HTTP $_SERVER[REQUEST_METHOD] method; \$_POST = ".var_export($_POST, 1);
?>

Теперь сделайте это:

  1. Откройте его в браузере Firefox (я создал демо здесь ; я использую 6.0.1 в Debian).
  2. Отправьте форму. Очевидно, браузер выполнил запрос HTTP POST. Обратите внимание, что HTTP-заголовок Refresh поставляется с ответом.
  3. Подождите 5 секунд. Теперь применяется заголовок Refresh, и местоположение будет перенаправлено на себя.
  4. Firefox выполнил запрос GET . Это определенно ПОЛУЧЕНО, потому что и Firebug, и PHP $_SERVER['REQUEST_METHOD'] говорят это.
  5. Нажмите клавишу F5. Поскольку последний выполненный HTTP-запрос был запросом GET, можно ожидать, что все данные POST из предыдущих запросов будут потеряны. Однако появляется диалоговое окно с просьбой повторно отправить данные POST:

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

Итак, мой вопрос - почему данные POST все еще здесь? Это ошибка или предполагаемое поведение? Обратите внимание, что использование любого из следующего приведет к потере данных POST (ожидаемое поведение):

  • Location заголовок вместо Refresh
  • Другое значение параметра URL= заголовка Refresh (пользователь будет перенаправлен в другое место).
  • Другой браузер (я тестировал Internet Explorer 9.0.2 и Chromium 6.0).

1 Ответ

4 голосов
/ 04 сентября 2011

Это не ошибка и не предполагаемое поведение.Причина этого заключается в том, что нет заголовка с именем Refresh:, определенного ни одним из HTTP RFC (в частности, RFC1945 и RFC2616 не упоминают об этом).Это означает, что, хотя большинство браузеров реализуют заголовок Refresh, как если бы это было мета-обновление, не существует ожидаемого поведения для этого, которое можно считать одинаковым во всех браузерах .

Оглядываясь вокруг StackOverflow и Интернета в целом кажется, что заголовок Refresh: был (как и многие другие) изобретен Netscape в первые дни Интернета и принятвсеми.В то время как многие из этих произвольных конструкций Netscape (, такие как Javascript ) были позже приняты в качестве отраслевых стандартов, заголовок Refresh: не был, потому что HTTP уже предусматривал эту функциональность с 3xx кодами ответа.

Суть этого заключается в том, что неудивительно, что разные браузеры обрабатывают его по-разному, потому что нет стандарта, который бы указывал разработчикам браузеров, как именно с ним обращаться.А по поводу использования заголовка в ваших приложениях - не надо.Легко и просто.Используйте 3xx перенаправления.Вот для чего они.И если вы используете его, потому что вам нужно обновить страницу после тайм-аута, используйте <meta> refresh - , в то время как теперь это официально устарело , оно должно обрабатываться везде одинаково.

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