коды состояния

3xx - класс ответов переадресации

Класс ответов связанных с переадресацией, используется для информирования агента пользователя (браузера) о том, что для завершения запроса необходим дополнительный запрос. Дополнительная информация содержится в заголовке Location. Это, как правило, адрес ресурса, к которому нужно совершить переадресацию. Исключением является ответ 304, который не имеет отношения к переадресации.

В протоколе HTTP/1.0 имелось четыре кода ответов 3xx: 300, 301, 302, 304. В HTTP/1.1 добавились 303, 305, 307, а 306 оказался промежуточным, который из конечной версии 1.1 был исключен.

Коды состояния
300 Multiple Choices	Переадресация с согласованием содержимого
301 Moved Permanently	Новое постоянное местоположение ресурса
302 Found			Временное местоположение ресурса по версии HTTP/1.0
303 See Other		Переадресация, как продолжение запроса
304 Not Modified		Подтверждение актуальности ресурса
305 Use Proxy		Повторить запрос через прокси сервер
306 (Unused)		Код вышедший из употребления
307 Temporary Redirect	Новое местоположение ресурса по версии HTTP/1.1

300 Multiple Choices — анг. множественный выбор. Данный ответ относится к механизму согласования содержимого со стороны пользователя. Ответом 300 сервер информирует пользователя, что имеется несколько представлений содержимого, которые находятся в разных местах и ему нужно выбрать одно из них. В содержимом ответа 300 сервер должен (SHOULD) послать все варианты представления содержимого и их местоположения, даже если запрос был осуществлен методом HEAD. Поскольку формат представления вариантов содержимого не стандартизирован, скорее всего, пользователь должен сделать выбор вручную. Наиболее предпочтительный из них сервер должен (SHOULD) поместить в заголовок Location.

301 Moved Permanently — анг. перемещен навсегда. Код 301 используется для указания того, что запрашиваемый ресурс имеет новое постоянное местонахождение. Ответ с кодом 301 является по умолчанию кэшируемым, если в заголовке Cache-Control не указано обратное. Если ответ кэшируется, то при повторном требовании ресурса А, прокси серверы, браузеры и поисковые машины будут сразу затребовать ресурс B, без перепроверки адреса А.

302 Found — анг. найден. В протоколе HTTP/1.0 описание этого ответа было другим: Moved Temporarily — анг. перемещен временно. В протоколе HTTP/1.1 было изменено только описание, а суть осталась та же. Код 302 является разновидностью ответа 301 в том смысле, что запрашиваемый ресурс также был перемещен, но не постоянно. В отличие от ответа 301, ответы с кодом 302 по умолчанию не кэшируются и клиенты будут продолжать использовать в будущих запросах старый URL. Однако кэширование может состояться, если в ответе присутствуют соответствующие заголовки Cache-Control или Expires.

В бытность ранних версий HTTP (еще до версии 1.0) некоторые разработчики браузеров допустили существенную ошибку, которая в последствии появилась в описании стандартов RFC 1945 и RFC 2616. При получении ответа с кодом 301 или 302, браузер делал запрос по адресу содержащемся в заголовке Location всегда методом GET, не взирая на метод первоначального запроса. Однако, согласно всем версиям протокола HTTP, если браузер при переадресации хочет изменить метод запроса, он должен спросить подтверждения у пользователя.
Чтобы как-то исправить эту ситуацию, в протоколе HTTP/1.1 были введены два новых кода ответа: 303 и 307. 303 — это узаконенная переадресация со сменой метода (ошибочный 302), 307 — альтернатива корректным 301 и 302 ответам.

303 See Other — анг. смотри другое. Ответ 303 был специально добавлен в новый протокол HTTP/1.1, как альтернатива некорректной обработке ответа 302. При получении ответа 303 браузер должен (SHOULD) перейти по другому адресу только методом GET без подтверждения пользователя. Этот ответ существует прежде всего для того, чтобы переадресовывать пользователя после POST-запроса. Таким образом, адрес содержащийся в заголовке Location не является заменой запрошенного ресурса, а лишь его продолжением. Поэтому, в отличие от ответа 302, ответ 303 никогда не кэшируется, даже если заголовок Cache-Control разрешает кэширование. Однако, это не распространяется на переадресованный ресурс.
Если вы опасаетесь, что браузер пользователя не поймет ответ 303, то вы должны использовать ответ 302.

Начиная со спецификации RFC 1945 протокола HTTP/1.0 говорилось о том, что некоторые браузеры неправильно обрабатывают ответ 302. Это дало точно противоположный эффект: сегодня в отношении ответа 302 стандарт всегда нарушается. Представьте себя на месте разработчиков новой версии браузера. Спецификация RFC 2616 прямо говорит о неоднозначности, сложившейся вокруг ответа 302. Ваш браузер должен обрабатывать этот ответ. Но как? Разработчики современных браузеров рассудили так: раз ответы 303 и 307 были предложены, как альтернатива ошибочной обработке ответа 302, то логично будет принять ошибочную стратегию обработки ответа 302. Что мы и имеем на сегодняшний день. Вопреки стандарту, все браузеры обрабатывают ответ 302 практически так же, как и 303: переадресация всегда совершается методом GET без подтверждения у пользователя.

304 Not Modified — анг. не изменен. Надо признать, что этот код не имеет отношения к переадресации и не требует наличия заголовка Location. Код ответа 304 используется в методе проверки актуальности ресурса совместно с заголовком ответа Last-Modified и заголовком запроса If-Modified-Since. Более подробно об этом методе написано в статье Управление кэшированием со стороны сервера в главе "Метод проверки актуальности".

305 Use Proxy — анг. использовать прокси сервер. Ответ 305 информирует пользователя о том, что запрос к запрашиваемому ресурсу должен осуществляться через прокси-сервер, URI которого указан в заголовке Location. Этот код был первоначально введен, чтобы снизить нагрузку на Web-сервер и настроить его так, чтобы он мог указывать каким прокси сервером должен пользоваться конкретный клиент.
Данный код ответа могут использовать только (MUST) исходные серверы. Нарушение этого условия влечет за собой возможность осуществления атаки типа промежуточного компонента (man-in-the-middle): некий промежуточный компонент переадресует запросы на «вражеский» прокси сервер.

306 (Unused) — анг. не используется. Ответ 306 был введен в одной из первых версий проекта спецификации HTTP и позже был исключен. Версия прокси-сервера компании Netscape расширяла требования для кода ответа 306 Switch Proxy таким образом, что получатель мог использовать прокси-сервер, указанный в новом заголовке промежуточных передач Set-proxy, для последующих запросов. Дополнение должно было, главным образом, добавить некоторую недостающую функциональность к семантике ответа 305 Use Proxy и ограничить область применения этого ответа прокси-серверами, а не Web-серверами. Однако беспокойство о последствиях этого ответа для безопасности (особенно в связи с атакой типа промежуточного компонента) привело к исключению в НТТР/1.1 кода состояния 306. Однако так как простое исключение может означать, что прежние реализации станут не работоспособными, этот код был зарезервирован.

307 Temporary Redirect — анг. временная переадресация. Код ответа 307 информирует пользователя, что данный ресурс временно находится по новому URI, записанному в заголовке Location.
Ответ 307 является альтернативой ответам 301 и 302. Если заголовок Cache-Control разрешает кэширование, то это будет альтернатива 301 (перемещен навсегда). Если заголовок отсутствует, или он явно запрещает кэширование, то это будет альтернатива 302 ответу (перемещен временно). Благодаря гибкости управления кэшированием с помощью заголовка Cache-Control можно указывать, на какое время был перемещен ресурс (директива max-age).

А теперь о том, как все на самом деле…

В реальности браузеры обрабатывают ответы переадресации во многом не так, как написано в спецификации протокола HTTP/1.1 Мною были рассмотрены следующие браузеры:

Internet Explorer 8.0.76 (2009)
FireFox 3.0.3 (2008)
Opera 8.51 (2005)
Internet Explorer 6.0.29 (2004)

Напомню, что спецификация RFC 2616 протокола HTTP/1.1 была выпущена в 1999 году.

Первое, что нужно отметить, это то, что ни один браузер не кэширует ответы класса 3xx. А это значит, что различия между ответами 301, 302 и 303 стираются окончательно. И так самое основное, что мы отмечаем: все рассмотренные браузеры обрабатывают ответы 301, 302 и 303 абсолютно одинаково. А именно: не кэшируют ответ, переадресацию всегда совершают методом GET без подтверждения пользователя.

А вот относительно ответа 307 все более радужно. Все браузеры, кроме Internet Explorer, полностью соответствуют стандарту. Браузеры FireFox и Opera при запросе методом POST и получении ответа 307 спрашивают пользователя, хочет ли он переадресовать POST-данные на другой ресурс. При получении подтверждения совершается POST запрос на новый ресурс. Браузер Internet Explorer отличается тем, что не спрашивает пользователя, и без получения подтверждения пересылает POST запрос на новый ресурс.