Blog. Just Blog

HTTP-заголовки на PHP: Status или HTTP/1.x?

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Для управления переадресацией, установки ответов сервера и передачи пользовательских заголовков в PHP используется функция Header. C ее помощью можно, например, установить статус ошибки 404, чтобы сообщить браузеру или поисковой системе, что такой страницы сайта больше не существует. В официальной документации такой случай описывается следующим образом:
  1. <?
  2. header ("HTTP/1.0 404 Not Found");
  3. ?>
Или же, как более корректный вариант:
  1. <?
  2. Header($_SERVER['SERVER_PROTOCOL']." 404 Not Found");
  3. ?>
Теперь приступим к тестам. Для проверки поведения скрипта возьмем менеджер закачек Download Master и браузер Firefox с дополнением LiveHTTPHeaders. В качестве тестовых систем для скрипта будут два локальных компьютера и хостинговый сервер. Конфигурация локальных машин: сервер Apache 1.3 и 2.0, PHP версии 5 установлен как CGI/FastCGI, операционная система Windows XP и Windows Seven. Результат плачевный: на обеих системах скрипт рушится с Internal Server Error, а в логе Apache ошибка записана как:

malformed header from script. Bad header=HTTP/1.1 404 Not Found

Хостинговый сервер ведет себя более дружелюбно. Конфигурация: Apache 1.3, PHP версии 4 установлен как CGI, операционная система Linux. При попытке "скачать" скрипт при помощи Download Master, его лог будет вполне ожидаемым, за исключением потери нашего сообщения, что файл не найден Not Found.

HTTP/1.1 404
Server: Apache/1.3.41 (Unix)
X-Powered-By: PHP/4.4.9
Connection: close
Content-Type: text/html; charset=windows-1251
Ошибка закачки. Запрашиваемый файл отсутствует на сервере. Закачка прервана.

Лог браузера Firefox еще более странный, хотя тоже похож на правду.

HTTP/1.x 404 OK
Server: Apache/1.3.41 (Unix)
X-Powered-By: PHP/4.4.9
Keep-Alive: timeout=15, max=300
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=windows-1251

Здесь наше сервисное сообщение Not Found вообще подменяется на OK, хотя статус 404 возвращается в обеих случаях правильно. Если скрипт на хостинговом сервере передает другие коды, например, 403 Access Denied или выполняет переадресацию через код 301 Moved Permanently, то браузер и менеджер закачки обрабатывают их так же корректно. На этом можно было бы почти успокоиться, если бы не популярная поисковая системы Google со своими "Инструментами для веб-мастеров". Тут картина не такая безоблачная: ни переадресации, ни статусы ошибок, переданные через HTTP/1.x, поисковым роботом Google не обрабатываются. Вообще. Если для странички про любимого хомячка Васи Пупкина это совсем не страшно, то серьезный интернет-проект может пострадать из-за неправильной индексации. А особенно это опасно, если после смены домена такая переадресация выполняется со старого сайта на новый, добытые тяжелым трудом позиции рейтинга могут серьезно пошатнуться. Как же быть? Решение очень простое, надо отправлять заголовки сервера через Status.
  1. <?
  2. header ("Status: 404 Not Found");
  3. ?>
Проверяем сперва локальные машины с Windows. Скрипт в браузере обрабатывается без единой ошибки, текст сообщения тоже на месте:

HTTP/1.x 404 Not Found
Server: Apache/1.3.41 (Win32)
X-Powered-By: PHP/5.2.9-2
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html

HTTP/1.x 404 Not Found
Server: Apache/2.2.8 (Win32)
X-Powered-By: PHP/5.2.9-2
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html

На сервере также все в полном порядке:

HTTP/1.x 404 Not Found
Server: Apache/1.3.41 (Unix)
X-Powered-By: PHP/4.4.9
Keep-Alive: timeout=15, max=299
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=windows-1251

Теперь попробуем повторить то же самое с менеджером закачек.

HTTP/1.1 404 Not Found
Server: Apache/1.3.41 (Win32)
X-Powered-By: PHP/5.2.9-2
Connection: close
Content-Type: text/html
Ошибка закачки. Запрашиваемый файл отсутствует на сервере. Закачка прервана.

HTTP/1.1 404 Not Found
Server: Apache/1.3.41 (Unix)
X-Powered-By: PHP/4.4.9
Connection: close
Content-Type: text/html; charset=windows-1251
Ошибка закачки. Запрашиваемый файл отсутствует на сервере. Закачка прервана.

Другие коды ошибок сервера, а также переадресации выполняются также корректно, с сохранением всех сообщений. Поисковые роботы Google такие конструкции обрабатывают тоже правильно, в панели управления сайтами никаких ошибок не фиксируется. Значит наша цель достигнута. Интересно, что в документации PHP оба способа описаны как равнозначные, но на практике получается, что корректным способом передачи статусов сервера из скрипта является все-таки Status, а не HTTP/1.x.

Поделиться ссылкой ВКонтакте
Просмотров: 10509 | Комментариев: 7

Метки: PHP, серверы
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
shomeax (13.11.2011 в 06:45):
статья ни о чем. падение зависит исключительно от конфигурации - если запуск через CGI или как модуль apache - используют header(), если fastcgi - header('Status:'). а надо было всего лишь внимательно почитать документацию.
Vit (14.03.2011 в 23:05):
для проверки результатов смены заголовка можно использовать также http://web-sniffer.net/
кстати, header("Status: 404 Not Found") - не работает как надо, а вот  header($_SERVER['SERVER_PROTOCOL']." 404 Not Found") - очень даже хорошо)
ipSlicer (09.12.2009 в 21:47):
Полезное наблюдение. Хостингов много и проблемы с ними по разным аспектам бывают регулярно. Одной меньше. Спасибо, приму к сведению.
ManHunter (09.12.2009 в 21:09):
Личный опыт. У меня тоже на блоге стояла переадресация только с HTTP, гугл упорно считал такие страницы ошибочными и не обрабатывал переход. Пришлось искать альтернативное решение, и вопрос был успешно решен заменой HTTP на Status. Потом еще немного поэкспериментировал, и написал эту статью.
ipSlicer (09.12.2009 в 21:07):
> ни переадресации, ни статусы ошибок, переданные через HTTP/1.x,
> поисковым роботом Google не обрабатываются. Вообще.
Интересная информация, а не подскажите ее источник? В руководсве вебмастеров Google я такого не нашел. Для склейки доменов постоянно использую: header("HTTP/1.0 301 Moved Permanently"); Для разных хостингов, в т.ч. и там где PHP установлен как FastCgi. Проблем пока не наблюдалось.
ManHunter (04.12.2009 в 18:59):
"Всю жизнь" - это на каких конфигурациях серверов? PHP собран как модуль апача или как CGI? Это на многое влияет. А свои тестовые конфигурации я подробно расписал.
semenov (04.12.2009 в 18:30):
Сдается мне, хостинг к вас тупит
Всю жизнь пользую Header($_SERVER['SERVER_PROTOCOL']." ..."); проблем не возникало

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.13 сек. / MySQL: 2 (0.0054 сек.) / Память: 4.5 Mb
Наверх