В чем разница между редиректом 302 и 307?

В чем разница между 302 FOUND и 307 TEMPORARY REDIRECT HTTP-ответом?

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


person Zach Hirsch    schedule 14.01.2010    source источник


Ответы (9)


Разница касается перенаправления запросов POST, PUT и DELETE и ожиданий сервера от поведения агента пользователя (_ 4_):

Примечание. RFC 1945 и RFC 2068 указывают, что клиенту не разрешено изменять метод перенаправленного запроса. Однако большинство существующих реализаций пользовательского агента обрабатывают 302, как если бы это был ответ 303, выполняя GET для значения поля Location независимо от исходного метода запроса. Коды состояния 303 и 307 были добавлены для серверов, которые хотят однозначно указать, какой тип реакции ожидается от клиента.

Также прочтите статью в Википедии о 30-кратных кодах перенаправления.

person Franci Penov    schedule 15.01.2010
comment
Итак, с точки зрения парсера / агента / браузера, мы можем просто рассматривать 302 и 307 как идентичные, верно? (В точности можно использовать один и тот же фрагмент кода для обработки обоих случаев без дальнейшего различия?) - person Pacerier; 17.01.2016
comment
Нет - вы можете рассматривать 302 и 303 как идентичные, но 307 - разные. - person Quentin Skousen; 02.06.2016
comment
@kkhugs, Ни в коем случае не нужен браузер 1.0, чтобы get-302 делал так же, как get-307 делается в браузерах 1.1. Браузер 1.0 должен выполнять post-302 так же, как и get-302, за исключением того, что для продолжения он должен сначала требовать подтверждения пользователя, а метод должен быть опубликован. - person Pacerier; 15.02.2017
comment
Браузер версии 1.1 необходим для выполнения get-302 так же, как и для get-307. - person Pacerier; 15.02.2017

307 возникло потому, что пользовательские агенты, принятые в качестве поведения де-факто, принимают запросы POST, которые получают ответ 302, и отправляют запрос GET в заголовок ответа Location.

Это неправильное поведение, только 303 должно превращать POST в GET. Пользовательские агенты должны (но не должны) придерживаться метода POST при запросе нового URL-адреса, если исходный запрос POST вернул 302.

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

person Christopher Orr    schedule 15.01.2010
comment
Есть ли примеры некорректных ответов пользовательских агентов? Обычно это очень небольшой процент посетителей? - person halfbit; 09.04.2011
comment
@ makerofthings7 Все браузеры неправильно обрабатывают 302. Chrome 30, IE10. Это стало де-факто некорректной реализацией; это не может быть изменено, потому что многие веб-сайты по ошибке выдают 302. На самом деле ASP.net MVC неправильно выдает 302, в зависимости от того факта, что браузеры обрабатывают его неправильно. - person Ian Boyd; 03.10.2013
comment
@IanBoyd Фреймворки делают это только потому, что 303 также был введен с 307 в спецификации HTTP 1.1 и, таким образом, обеспечивает обратную совместимость с пользовательскими агентами HTTP 1.0. Конечно, реальный вопрос заключается в том, должны ли мы вообще сейчас обрабатывать пользовательские агенты HTTP 1.0? - person ewanm89; 09.04.2014
comment
@ ewanm89 Похоже, фреймворк может создать метод ответа с правильным именем (например, Response.RedirectSeeOther), и если клиент не 1.1 (например, GET /foo.html, GET /foo.html HTTP/1.0), то выдать устаревший 302. - person Ian Boyd; 09.04.2014
comment
При редиректе это выглядит как 302 = 303. - person vee; 17.06.2019

Хороший пример 307 Internal Redirect в действии - это когда Google Chrome обнаруживает HTTP-вызов к домену, который, как ему известно, требует строгой транспортной безопасности.

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

Внутреннее перенаправление HTST 307

person Kristian Williams    schedule 01.05.2015
comment
Вы знаете, когда Google реализовал эту функцию? - person Tijme; 11.06.2015
comment
Да, это то место, где я вижу, что это происходит - наш сервер не отправляет это - в chrome devtools похоже, что это так, но это просто хром, выполняющий перенаправление, потому что у нас есть заголовок Strict Transport Security - person mike nelson; 16.10.2017

Блок-схема

  • 301: постоянное перенаправление: старый URL-адрес должен быть заменен. Браузеры будут кэшировать его.
    Пример использования: URL-адрес перемещен с /register-form.html на signup-form.html.
    изменится на GET согласно RFC 7231: «По историческим причинам пользовательский агент МОЖЕТ изменить метод запроса с POST на GET для последующего запроса».
  • 302: временное перенаправление. Используйте только для клиентов HTTP / 1.0. Этот код состояния не должен изменять метод, но браузеры все равно это сделали. В RFC говорится: «Многие пользовательские агенты до HTTP / 1.1 не понимают [303]. Когда взаимодействие с такими клиентами вызывает беспокойство, вместо этого может использоваться код состояния 302, поскольку большинство пользовательских агентов реагируют на ответ 302, как описано здесь за 303. " Конечно, некоторые клиенты могут реализовать это в соответствии со спецификацией, поэтому, если совместимость с такими древними клиентами не является реальной проблемой, 303 лучше для согласованных результатов.
  • 303: временное перенаправление, изменение метода на GET.
    Пример использования: если браузер отправил POST на /register.php, теперь загружается (GET) /success.html.
  • 307: временное перенаправление, идентичное повторение запроса.
    Пример использования: если браузер отправил POST на /register.php, то это говорит ему повторить POST на /signup.php.
  • 308: постоянное перенаправление, идентичное повторение запроса. Где 307 - это "нет изменения метода", аналог 303, этот статус 308 - "нет изменения метода", аналог 301.

RFC 7231 (от 2014 г.) очень удобочитаем и не слишком подробен. Если вы хотите узнать точный ответ, рекомендуется прочитать это. В некоторых других ответах используется RFC 2616 от 1999 года, но ничего не изменилось.

RFC 7238 определяет статус 308. Это считается экспериментальным, но он уже поддерживался всеми основными браузерами в 2016 г.

person Luc    schedule 05.03.2019
comment
302 не является устаревшим. - person Julian Reschke; 05.03.2019
comment
@JulianReschke Википедия говорит, что 302 был заменен 303 и 307. Возможно, это потому, что я не носитель языка, но для меня (в этом контексте) замененный и устаревший означает то же самое: либо используйте 303 или 307, но не 302. Am Я неправильно это читаю? - person Luc; 06.03.2019
comment
Что неверно, так это предположение, что Википедия говорит об этом. Если 302 устарел, так будет сказано в протоколе HTTP. - person Julian Reschke; 06.03.2019
comment
@JulianReschke Достаточно честно, я обратился к источнику и waddayaknow? Вы совершенно правы. RFC на самом деле очень понятен, и они даже рекомендуют 302 под определенные условия. Ни один из обновленных и устаревших RFC, упомянутых выше, не касается кодов состояния, поэтому я полагаю, что этот документ 1999 года действительно является последним из имеющихся у нас. Я обновлю свой ответ. - person Luc; 06.03.2019
comment
Важным является реестр кода состояния IANA и, следовательно, в данном случае RFC 7231. - person Julian Reschke; 06.03.2019
comment
@JulianReschke Я видел это, когда редактировал свой ответ и перечитывал некоторые вещи. Обновил мой ответ сейчас, еще раз спасибо! - person Luc; 06.03.2019
comment
Ответ пока неверный. 302 вообще не является устаревшим и может быть использован. См. greenbytes.de/tech/webdav/rfc7538.html#introduction (который кстати, не больше экспериментальный). Не путайте 303 с набором 301/302/307/308. - person Julian Reschke; 06.03.2019
comment
Позвольте нам продолжить это обсуждение в чате. - person Luc; 06.03.2019

Изначально было просто 302

Response What browsers should do
302 Found Redo request with new url

Идея в том, что:

  • если бы вы выполняли GET в каком-то месте, вы бы переделали свой GET на новый URL
  • если бы вы выполняли POST в каком-то месте, вы бы переделали свой POST на новый URL
  • если бы вы выполняли PUT в каком-то месте, вы бы переделали свой PUT на новый URL
  • если бы вы выполняли DELETE в каком-то месте, вы бы переделали свой DELETE на новый URL
  • так далее

К сожалению, каждый браузер делал это неправильно. При получении 302 они всегда переключались на GET с новым URL-адресом, вместо того, чтобы повторять запрос с той же командой (например,, POST):

  • Мозаика сделала это неправильно
  • Netscape скопировал ошибки в Mosaic; так они ошиблись
  • Internet Explorer скопировал ошибки в Netscape; так они ошиблись

Это стало де-факто ошибкой.

Все браузеры ошиблись 302. Так были созданы 303 и 307.

Response What browsers should do What browsers actually do
302 Found Redo request with new url GET with new url
303 See Other GET with new url GET with new url
307 Temporary Redirect Redo request with new url Redo request with new url

В виде диаграммы

5 различных видов переадресации:

╔═══════════╦════════════════════════════════════════════════╗
║           ║                Switch to GET?                  ║
║           ║────────────────────────┬───────────────────────╢
║ Temporary ║          No            │         Yes           ║
╠═══════════╬════════════════════════╪═══════════════════════╣
║ No        ║ 308 Permanent Redirect │ 301 Moved Permanently ║
╟───────────╫────────────────────────┼───────────────────────╢
║ Yes       ║ 307 Temporary Redirect │ 303 See Other         ║
║           ║ 302 Found (intended)   │ 302 Found (actual)    ║
╚═══════════╩════════════════════════╧═══════════════════════╝

Альтернативно:

Response Switch to get? Temporary?
301 Moved Permanently No No
302 Found (intended) No Yes
302 Found (actual) Yes Yes
303 See Other Yes Yes
307 Temporary Redirect No Yes
308 Permanent Redirect No No
person Ian Boyd    schedule 21.10.2019

ОЖИДАЕТСЯ для 302: перенаправление использует тот же метод запроса POST на NEW_URL

CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT POST NEW_URL

ACTUAL для 302, 303: перенаправление изменяет метод запроса с POST на GET на NEW_URL

CLIENT POST OLD_URL -> SERVER 302 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)
CLIENT POST OLD_URL -> SERVER 303 NEW_URL -> CLIENT GET NEW_URL (redirect uses GET)

ФАКТИЧЕСКИЙ для 307: перенаправление использует тот же метод запроса POST на NEW_URL

CLIENT POST OLD_URL -> SERVER 307 NEW_URL -> CLIENT POST NEW_URL
person Roy Hyunjin Han    schedule 20.06.2017

302 - это временное перенаправление, которое генерируется сервером, тогда как 307 - это внутренний ответ перенаправления, генерируемый браузером. Внутреннее перенаправление означает, что перенаправление выполняется автоматически внутренним браузером, в основном браузер изменяет введенный URL-адрес с http на https в запросе получения перед отправкой запроса, поэтому запрос на незащищенное соединение никогда не отправляется в Интернет. Будет ли браузер изменять URL-адрес на https или нет, зависит от списка предварительной загрузки hsts, который предустановлен вместе с браузером. Вы также можете добавить любой сайт, поддерживающий https, в список, указав домен в списке предварительной загрузки hsts вашего собственного браузера, который находится по адресу chrome: //net-internals/#hsts. Их владельцы могут добавить еще домены веб-сайтов. для предварительной загрузки списка, заполнив форму на https://hstspreload.org/, чтобы он был предустановлен в браузерах для каждый пользователь, даже если я упоминаю, вы можете сделать и для себя лично.


Позвольте мне объяснить на примере:
Я сделал запрос на получение на http://www.pentesteracademy.com, который поддерживает только https, и у меня нет этого домена в моем списке предварительной загрузки hsts в моем браузере, поскольку владелец сайта не зарегистрировался для того, чтобы он поставлялся с предварительно установленным списком предварительной загрузки hsts. заголовки запроса и ответа
Запрос GET для незащищенной версии сайта перенаправляется на защищенную версию (см. заголовок http с именем location для этого в ответе на изображении выше).
Теперь я добавляю сайт в свой список предварительной загрузки браузера, добавляя его домен в форму «Добавить домен hsts» по адресу chrome: // net-internals / # hsts, который изменяет мой личный список предварительной загрузки в моем браузере Chrome. Обязательно выберите включить там поддомены для STS.
Давайте теперь посмотрим на запрос и ответ для того же веб-сайта после добавления его в список предварительной загрузки hsts.
 заголовки запроса и ответа
вы можете увидеть внутреннее перенаправление 307 там в заголовках ответов, на самом деле этот ответ генерируется вашим браузером, а не сервером.
Также список предварительной загрузки HSTS может помочь предотвратить доступ пользователей к незащищенной версии сайта, поскольку перенаправление 302 подвержено атакам mitm.
Надеюсь, я немного помог вам разобраться в перенаправлениях.

person Simranjeet Singh    schedule 28.05.2020
comment
307: Сделано браузером внутренне с использованием списка предварительной загрузки HSTS - это именно то, что я хотел услышать. Спасибо за подтверждение! - person krozaine; 02.01.2021

Кроме того, для администраторов серверов может быть важно отметить, что браузеры могут отображать подсказку пользователю, если вы используете перенаправление 307.

Например, * Firefox и Opera будут запрашивать у пользователя разрешение на перенаправление, тогда как Chrome, IE и Safari будут выполнять перенаправление прозрачно.

* на Bulletproof SSL и TLS (стр. 192) .

person Pacerier    schedule 10.11.2016
comment
Это верно только для небезопасных запросов, таких как POST. - person Julian Reschke; 11.11.2016

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

Дополнительную информацию можно найти в разделе 3.1 документа Комплексный формальный анализ безопасности OAuth. 2.0.

Авторы указанной статьи предлагают следующее:

Исправление. В отличие от текущей формулировки стандарта OAuth, точный метод перенаправления не является деталью реализации, но необходим для безопасности OAuth. В стандарте HTTP (RFC 7231) однозначно определено только перенаправление 303 для удаления тела запроса HTTP POST. Все остальные коды состояния перенаправления HTTP, включая наиболее часто используемый 302, оставляют браузеру возможность сохранить запрос POST и данные формы. На практике браузеры обычно переписывают запрос GET, тем самым удаляя данные формы, за исключением 307 перенаправлений. Поэтому стандарт OAuth должен требовать 303 перенаправления для шагов, упомянутых выше, чтобы решить эту проблему.

person M.S. Dousti    schedule 08.07.2017