Несуществующие страницы
У статического сайта нет проблем с ненайденными страницами – каждая страница хранится в своем html-файле; не найдя запрошенного файла, веб-сервер автоматически отправляет заголовок с кодом статуса 404. И следом страничку с текстовым сообщением об ошибке. Первое для роботов, второе для людей.
В случае движка не все так просто. Есть ли псевдостатический URL или нет – все равно запрос будет исполнен в реальном формате – имя файла скрипта и параметры. Причем, чаще всего скрипт один и тот же для большинства страниц. Какая именно страница будет сформирована, определяется параметрами. Если запросить имя несуществующего скрипта, сервер исправно выдаст статус 404. А если имя скрипта верное, но неверные параметры? Такая страница не создавалась, но файл скрипта на своем месте – сервер готовит заголовок со статусом «200 OK» и запускает скрипт.
В этом случае только скрипт может обработать ошибочный запрос и переписать поле статуса в заголовке до его отправки. Вот эту особенность часто упускают из виду начинающие. Часто скрипт даже не опрашивает элементы массива $_GET, а использует порожденные из них автоглобальные переменные с теми же именами. Те, что нужны для генерации страницы и не более. Если переданы лишние параметры, соответствующие переменные будут созданы, но скрипт о них ничего «не знает».
В итоге страница с адресом /index.php?section=1&page=2 будет сформирована по любому запросу, в который войдут эти два параметра. Можно добавить третий параметр с любым именем и значением, скрипт сгенерирует ту же страницу. Но ссылка /index.php?section=1&page=2&qq=asdf – это уже совсем другой адрес с точки зрения поисковой системы. Если ПС где-то встретит такую ссылку и получит по ней ту же страницу, в индексе появится дубликат.
Подробнее об опасности таких дубликатов поговорим в разделе «SEO», когда он откроется. Сейчас достаточно сказать, что дубликатов быть не должно ни в коем случае. Что нам нужно для этого сделать?
- в скрипте должен храниться список используемых GET-переменных и в самом начале работы нужно сверять массив $_GET с этим списком – не передана ли лишняя переменная, которой в списке нет.
- нужно проверять значения GET-переменных на соответствие заданному типу данных и формату – особенно в том случае, если переменные используются при формировании запроса к базе данных. Иначе можно мимоходом получить и SQL-инъекцию.
- наконец, нужно проверять эти значения на достоверность. Например, параметр page=4, а в данных его значение может быть не больше 3.
- и в случае отсутствия параметров в массиве $_GET нужно проверить еще переменную окружения QUERY_STRING. Если URL имеет вид вроде http://domain.ru/?= то в $_GET не будет ни одного элемента, но в QUERY_STRING попадает все, что стоит в URL после знака вопроса.
Во всех случаях несоответствия параметров скрипт должен отправлять HTTP-заголовок с кодом статуса «404 Not Found», следом максимально легкую HTML-страничку с сообщением об ошибке и немедленно прекращать работу.
При этом все проверки должны проводиться до того, как скрипт начнет выводить какой-либо контент. Как только скрипт начнет выводить «тело» страницы, сервер сначала отправит заголовок, который он сформировал, а уж следом за ним начнет передавать вывод скрипта. После этого попытка скрипта передать заголовок приведет к ошибке и выполнение скрипта будет прервано.
Вот такое несложное дополнение к основному алгоритму скрипта позволит обработать неверные запросы и избежать дублирования страниц. А заодно повысит защищенность сайта (немалая часть хакерских атак проводится с использованием некорректных GET-параметров). Пример реализации обработчика ошибок есть в статье «Проверка корректности запроса» (раздел «Строим CMS»).