Перейти к содержанию
Yavid Vrn

307 редирект

Вы замечали, что POST-запрос вдруг становится GET после редиректа? Между кодом 301 moved permanently (постоянное перенаправление) и кодом 307 (временное перенаправление) есть фундаментальная разница при работе браузера на стороне клиента: первый код ответа преобразует любой метод запроса в GET, второй означает сохранение исходного запроса.

Это критично для выполнения запроса. Форма отправляет POST на сервер, получает код 301 вместо необходимого временного перенаправления на новый url адреса сайта — данные пользователя теряются при передаче между серверами. Сервер отправляет код ответа HTTP, браузер его обрабатывает на стороне клиента, результат зависит от выбора статус кода состояния. Для backend-разработчика это часы отладки, для SEO — потеря трафика между страницами сайта. Поисковые системы обрабатывают этот тип перенаправления по-разному в зависимости от применяемого кода.

307 редирект: что означает код состояния и как он отличается от 301, 302, 303 и 308

Посылка идёт по временной объездной дороге между серверами с обратной стрелкой
Сравнение кодов HTTP редиректов: сохранение методов запроса при 307 Temporary Redirect

Техническое определение и парадокс временного постоянства

Код состояния 307 Temporary Redirect в стандарте RFC 7231 описывается как временное перенаправление, которое сохраняет исходный метод запроса. Здесь скрывается ключевое отличие: обычно слово «временный» противопоставляют «постоянному», но в контексте кодов ответа HTTP это разные измерения. Постоянность редиректа (кешируется ли он браузером) — это одно. Сохранение метода запроса — совсем другое и требует понимания технических особенностей протокола HTTP при работе браузеров на стороне клиента.

Когда сервер отправляет ответ на запрос клиенту с кодом состояния 307 и заголовком Location, браузер должен повторить исходный запрос с тем же методом, который был изначально применен. Если исходный запрос был методом POST, браузер отправит данные POST к новому url адресу. Если это был GET, получится GET. Никаких преобразований. Это гарантирует, что данные пользователя сохраняются при обработке запроса и передаче между серверами.

Конкретный пример: форма и потеря данных

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

Затем вы решили переместить обработчик на другой сервер. Настраиваете редирект с кодом ответа 301 moved permanently для постоянного перенаправления. Что происходит дальше при выполнении запроса?

Браузер получает код 301, запоминает эту информацию в своем кеше, и в следующий раз вместо отправки POST-запроса отправит GET к новому адресу. Данные пользователя теряются. Сервер получает пустой запрос, форма перестаёт работать и не сообщает об ошибке.

Если бы вы вместо 301 использовали код 307 temporary redirect, браузер повторил бы POST к новому url. Все данные дошли бы целиком, функциональность сохранилась. Вот в чем критическое отличие для backend-разработчиков при выполнении запроса к серверу.

Сравнение редиректов: 301, 302, 303, 307, 308

301 Moved Permanently (перемещено навсегда). Это постоянное перенаправление, которое браузер кеширует надолго. В исторической перспективе браузер может преобразовать POST в GET. Старые версии протокола HTTP позволяли браузеру менять метод при 301. Даже сейчас некоторые клиенты это делают. Код состояния 301 означает, что ресурс перемещён навсегда на новый url адреса.

302 Found (найден). Это временное перенаправление, но его поведение в браузере примерно такое же, как у 301 moved permanently. Код раньше назывался «Found», смысл — «ресурс найден по другому адресу, но это временно». Браузер может преобразовать POST в GET. Кешируется короче, чем 301, что позволяет быстрее обрабатывать запрос при изменении расположения контента.

303 See Other (смотрите другое). Этот код существует специально для одной задачи: перенаправить с явным требованием выполнения запроса методом get. Применяется после обработки отправки формы — сервер подтверждает получение данных кодом 303 и указывает на новую страницу результата. Браузер всегда повторит запрос как GET, независимо от исходного метода. Это полезно для выполнения POST-запроса с последующим отображением результатов.

307 Temporary Redirect. Временное перенаправление с гарантией сохранения метода запроса. Браузер не кеширует этот код надолго. Каждый раз клиент должен выполнить новый запрос и получить свежее указание о редиректе. Если первый запрос был POST, повторный — тоже POST. Это означает, что данные сохраняются и передаются на новый url без потери информации.

308 Permanent Redirect (постоянное перенаправление). По сути, это полный аналог кода 301 moved permanently, но с одной существенной гарантией: метод запроса сохраняется полностью. Это постоянное перенаправление, браузер кеширует его, но при повторных обращениях применяет исходный метод клиента. Код 308 был добавлен позже для решения проблемы 301 с потерей методов запроса. Существуют и другие коды состояния: 200 ok (успешный ответ на запрос), 300 multiple choices (несколько вариантов), 304 not modified (содержимое не изменилось), 400 bad request (ошибочный запрос), 401 authentication required (требуется аутентификация), 410 gone (ресурс удален), 429 too many requests (слишком много запросов), 500 internal server error (ошибка сервера).

Почему разработчики выбирают неправильный код

Большинство используют 301 или 302 found для всех редиректов, предполагая, что разница только в постоянности. На малых сайтах это может незаметно работать без критических ошибок. Но когда появляются формы, API, внутренние POST-запросы — выбор кода ответа становится критичным. Потеря отправки POST-данных означает потерю ценной информации, на отладку которой уходят часы. Сервер логирует ошибку в технических системах, разработчик отправляет запрос заново, видит, что код ответа 301 преобразовал метод запроса в GET, и наконец понимает, что произошло.

Правило простое: если нужно временно перенаправить POST на другой обработчик или новый сервер, следует использовать 307 temporary redirect. Если миграция постоянная, выбирайте 308 permanent redirect. Если хотите явно использовать метод GET, выбирайте 303 see other.

Как поисковые системы это обрабатывают

Для SEO эта разница менее острая, но тоже важна. Поисковые системы передают вес ссылки через все типы редиректов одинаково — будь то 307 или 301. Робот Яндекса, Google, других поисковых систем следует за кодами 3xx и передает authority новому url адресу. Это применяется в равной степени ко всем типам перенаправлений на стороне поисковых алгоритмов и индексации.

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

Как использовать 307 редирект: сценарии применения, примеры кода и возможные ошибки

В каких четырёх сценариях применяют 307 редирект?

Код 307 temporary redirect применяется в четырёх практических сценариях, каждый требует сохранения метода запроса и данных отправки формы. Первый — временная миграция API эндпоинта. Новый сервер уже готов, но план изменился и переезд отложился. Следует использовать именно 307, потому что браузер клиента автоматически отправит новый запрос с тем же методом POST и всеми данными, не преобразуя их в GET.

Это критично для платёжных систем, форм входа и сбора персональных данных. Второй сценарий — A/B тестирование с сохранением исходного запроса. Когда нужно протестировать новый вариант url, но при этом сохранить функциональность обработки форм и точность аналитики на стороне сервера. Третий — временное изменение URL при редизайне сайта. Код 307 temporary redirect не кешируется браузером постоянно, поэтому возможна отмена редиректа, если потребуется.

Четвёртый сценарий — переключение нагрузки между серверами при техническом обслуживании. Основной на обслуживании, трафик перенаправляется на резервный сервер с полным сохранением исходного запроса и созданием резервной копии данных. Поисковые системы видят временный характер через код 307 и продолжают индексировать старый url как основной ресурс.

Как настроить 307 редирект в коде и конфигурации сервера?

На стороне сервера реализация различается синтаксисом при выполнении кода. Node.js Express используют res.redirect(307, '/new-page'). Python Flask применяет redirect(request.url.replace(old_url, new_url), code=307). Django требует явную response с указанием статус кода 307, потому что встроенная функция redirect() выдаёт 302. В PHP нужна строка header('HTTP/1.1 307 Temporary Redirect') с заголовком Location: /new-url.

На уровне веб-сервера nginx используют конструкцию return 307 $scheme://$server_name$request_uri; внутри блока location. Apache применяет mod_rewrite: RewriteRule ^old-page/?$ /new-page [R=307,L]. Прокси-сервера должны передавать заголовок Location без искажений, иначе клиент потеряет адрес назначения для обработки запроса на стороне веб-сервера.

Все эти подходы требуют в ответе сервера заголовок Location с полным адресом нового ресурса. Каждый пример кода указывает на новый url для перенаправления клиента. При конфигурации обязательно проверьте синтаксис, чтобы код ответа 307 был отправлен корректно и в заголовке location содержалась правильная информация.

Как проверить 307 редирект и избежать частых ошибок?

Самая дорогостоящая ошибка при обработке редиректа — использование кода 301 moved permanently для временных перенаправлений. Браузер кеширует 301 постоянно, и будущие запросы к старому url больше не достигают сервера. Если потом отменить редирект, пользователь об этом не узнает. Поисковые системы запомнят 301 навсегда, переиндексация займёт недели. Вторая ошибка — отсутствие заголовка Location в ответе сервера.

Браузер получит 307, но не узнает, куда идти и обработать запрос. Третья — неправильная regex в nginx или Apache, когда условие не матчит нужные пути. Четвёртая — игнорирование query-параметров: старый url с ?id=5 должен сохранить параметры на новый url при повторении запроса. При HTTPS проверьте совпадение протокола на обоих серверах. Для проверки используйте curl -i, это покажет код 307 и все заголовки ответа сервера.

DevTools Network визуализирует цепочку редиректов на стороне клиента. Убедитесь, что Location содержит правильный адрес для перенаправления. Протестируйте на реальных POST-запросах с данными через формы и загрузку файлов, чтобы убедиться, что отправки не потеряются при перенаправлении, и проверьте производительность на нагрузку от множественных редиректов одновременно.

Наверх