Будет ли всегда выполняться весь код после заголовка перенаправления в PHP?


Итак, я знаю, что общее эмпирическое правило заключается в том, что после перенаправления заголовка в PHP вам следует вызвать exit(), чтобы избежать запуска дополнительного кода, но я хочу знать, помещаете ли вы код после заголовка перенаправления, если он будет всегда выполняться?

Я проводил небольшое исследование различных способов отслеживания рефералов в Google Analytics и наткнулся на это сообщение: Советы и рекомендации Google Analytics – Отслеживание 301 перенаправления в Google Analytics

Он рекомендует что-то сделать вот так:

<?
Header( “HTTP/1.1 301 Moved Permanently” );
Header( “Location: http://www.new-url.com” );
?>

<script type=”text/javascript”>
var gaJsHost = ((“https:” == document.location.protocol) ? “https://ssl.” : “http://www.”);
document.write(unescape(“%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));
</script>
<script type=”text/javascript”>
try {
var pageTracker = _gat._getTracker(“UA-YOURPROFILE-ID”);
pageTracker._trackPageview();
} catch(err) {}</script>

Из того, как я всегда понимал функцию header(), это зависит от браузера, и он может запускать перенаправление, когда захочет. Таким образом, нет никакой гарантии, что JavaScript действительно начнет или завершит выполнение до того, как произойдет перенаправление.

Документация PHP для функции header() указывает, что причина выхода после перенаправления заключается в том, чтобы "убедиться, что приведенный ниже код не выполняется при перенаправлении". Это не похоже на то, что они гарантируйте, что весь следующий код будет запущен, просто чтобы это могло произойти.

Несмотря на это, я нашел другой способ фактически управлять отслеживанием, но я хотел посмотреть, смогу ли я узнать, как именно header() работает в этой ситуации..

Спасибо за вашу помощь.

Author: David Stinemetze, 2011-08-30

5 answers

Использование функции заголовка в PHP только добавляет к заголовкам ответа, возвращаемого сервером. Он не сразу отправляет какие-либо данные и не сразу прерывает соединение. Любой код после header вызова будет выполнен.

В частности, рекомендуется добавлять тело ответа даже после выполнения перенаправления 301, чтобы клиенты, которые не поддерживают перенаправление, также получали некоторый описательный ответ. Действовать в соответствии со спецификацией HTTP 1.1 Раздел 10.3.2 -

Если метод запроса не был HEAD, сущность ответа ДОЛЖНА содержать короткую гипертекстовую заметку с гиперссылкой на новый URI(ы). Если код состояния 301 получен в ответ на запрос, отличный от ПОЛУЧИТЬ или ВОЗГЛАВИТЬ, агент пользователя НЕ ДОЛЖЕН автоматически перенаправлять запрос, если он не может быть подтвержден пользователем, так как это может измените условия, на которых был выдан запрос.

 3
Author: Anupam Jain, 2011-08-30 17:45:01

Это условие гонки. Как только заголовок перенаправления будет отправлен в браузер, браузер закроет текущее соединение и откроет новое для URL-адреса перенаправления. До тех пор, пока это исходное соединение не будет закрыто и Apache не завершит работу скрипта, ваш код будет продолжать выполняться, как и раньше.

Теоретически, если бы между клиентом и сервером было достаточно быстрое соединение и нигде в конвейере не было буферизации, выдача заголовка привела бы к завершению сценария немедленно. На самом деле, это может быть где-то между "сейчас" и "никогда" для инициирования выключения.

 3
Author: Marc B, 2011-08-30 16:39:46

HTML после строки вашего местоположения не запускается внутри PHP; он будет работать в браузере. От браузера зависит, выполнять или нет Javascript, который вы включили на этой странице; PHP не имеет к этому никакого отношения.

Для меня документы PHP подразумевают, что любой PHP ниже header() при отправке перенаправления будет продолжать выполняться. Но он "запускается" в интерпретаторе PHP, сбрасывая JS в браузер. Нет никакой связи между тем, что говорится в документах PHP, и тем, запускается JS или нет с помощью браузера.

 0
Author: Jonathan, 2011-08-30 16:41:25

РЕДАКТИРОВАТЬ:

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

Это не похоже на то, что они гарантируют, что весь следующий код будет выполняться

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

Таким образом, нет никакой гарантии, что JavaScript действительно начнет или завершит выполнение до того, как произойдет перенаправление.

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

 0
Author: Your Common Sense, 2011-08-30 17:46:40

Я заметил, что код все еще выполняется, и несколько заголовков, основанных на операторах if, могут вызвать "ошибку цикла перенаправления". я взял за привычку добавлять die("Redirecting..."); после каждого перенаправления заголовка и не вижу, чтобы проблема сохранялась.

 0
Author: user1014899, 2014-02-17 13:59:57