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

Для управления переадресацией, установки ответов сервера и передачи пользовательских заголовков в PHP используется функция Header. C ее помощью можно, например, установить статус ошибки 404, чтобы сообщить браузеру или поисковой системе, что такой страницы сайта больше не существует. В официальной документации такой случай описывается следующим образом:
<?
header ("HTTP/1.0 404 Not Found");
?>

Или же, как более корректный вариант:
<?
Header($_SERVER['SERVER_PROTOCOL']." 404 Not Found");
?>

Теперь приступим к тестам. Для проверки поведения скрипта возьмем менеджер закачек 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.
<?
header ("Status: 404 Not Found");
?>

Проверяем сперва локальные машины с 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.
Добавлено: 12 Сентября 2013 05:00:48 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...