Хитрый 404|Настраиваем HTTP 404 на блоге
Про несуществующие страницы на блогах написано достаточно — об иерархии шаблонов темы, как правильно сделать 404, есть и подборка неплохих 404-страниц (в которую почему-то не вошли клеви лепро-дёти несуществующие страницы). Для регистрации всех обращений к 404 можно использовать и плагин вездесущего AlexKing'а, по ходу дела настругавшего миллион разнообразных дополнений к Вордпрессу.
Да тот же Кодекс предлагает отслеживать все ошибки и возвращать не только 404, но и 403, 502 и даже экзотический 402 Payment Required.

Но мне лично не нравится то, что запрошенный и не существующий URL так и останется висеть в адресной строке браузера, пока нам будут показывать соответствующие разъяснения и извинения. Плюс может возникнуть ситуация «мягкого 404», когда сервер будет посылать заголовок 200 «Все нормально», а сам говорить пользователю, что страницы нет.
Some websites report a „not found“ error by returning a standard web page with a „200 OK“ response code; this is called a soft 404. Soft 404s are problematic for automated methods of discovering whether a link is broken.
все та же вики
К счастью, хоть сам умный Wordpress сам отдает HTTP заголовок при попадании на 404 — ведь эта информация обрабатывается поисковиками. Но т.к. это делается только для ЧПУ лучше использовать прямую отдачу заголовков в шаблоне 404.php (а в случае нормального сайта или CMS — не забыть):
<?php ob_start();
header("HTTP/1.1 404 Not Found");
header("Status: 404 Not Found"); ?>
...содержание шаблона...
<?php ob_end_flush();
exit; exit(); ?>
С включенной буфферизацией ввода (которая, в принципе, тоже избыточна) мы создаем нужный нам HTTP-заголовок (второй, со статусом — по привычке, для невероятного случая с невероятным PHP 3), а потом выводим буффер. Внутри же — выдаем хедер, сайдбар и тот контент, который увидит пользователь, промахнувшийся мимо странички.
Но этим не решить ситуацию с «зависшим» URL. Одновременно надо учитывать, что переход на шаблон 404.php движком осуществляется только с включенным ЧПУ и если пользователь не напрямую передает правильные переменные через $POST или $GET. Т.е. при обращении к http://iskariot.ru/?cat=1211 сработает шаблон category.php — для это в темах обычно делают проверку на существование записей, и по else выводят соответствующее сообщение. Мало того, что это порождает необходимость писать подобное во всех необходимых шаблонах (избыточность), так еще по HTTP будет отдано 200 OK.
Более лаконичный и правильный способ — убрать вообще проверку if (have_posts ()) во всех этих шаблонах и делать ее раньше всего, в случае отсутствия записей — перенаправлять уже на несуществующую страницу без передачи переменных. Для этого мы вставим в самое начало header.php этот код:
<?php
if(!have_posts()&&($_SERVER['REQUEST_URI']!='/404/')) {
Header('Location: '.get_bloginfo('url').'/404/');
exit;
} ?>
Соответственно, мы проверяем на наличие постов и, если их нет — отправляем пользователя по 302 редиректу на страницу вида http://iskariot.ru/404/, где его уже ждет приятная неожиданность. Вторая проверка на запрашиваемый URI делается для того, чтобы при использовании в шаблоне 404.php хедера ничего не зацикливалось. Естественно, если несуществующая страница не использует основной хедер блога, то придется эту же проверку использовать и в нем.
Наконец, отправляем в самое начало .htaccess в корневой папке строчку:
ErrorDocument 404 /404/
для того, чтобы быть полностью уверенным в том, что все, кому надо (в первую очередь, Яндекс с Гуглом) обязательно поняли бы, что это именно несуществующая страница, а не какая-нибудь другая.
Если же нам не нужен редирект и мы хотим, чтобы в строке адреса все-таки оставался неправильно введенный URL (но отсылались нормальные заголовки), в хедере вместо выше написанного используем следующий код:
<?php if(!have_posts()&&!is_404()) {
include_once('404.php');
exit;
} ?>
Проверить результат теперь можно с помощью просмотрщика отдаваемых HTTP-заголовков. Несмотря на двойную отдачу заголовка, все работает корректно.
Вот и все — все дырки с HTTP-заголовками и 404 страницой мы закрыли, теперь она находится в одном месте и никуда больше не денется. Остается только придумать, как обустроить ее внутренности — лучшим вариантом, на мой взгляд, будет выдать на ней ссылку на главную страницу, архивы и популярные посты. Ну и следовать прочим уже много раз разъясненным правилам.




В смысле? Нахера при 404 ошибке рерайтить на какую-то другую страницу? Адрес должен оставаться в строке адреса!!1111
Возможно, ты и прав. Делают и так, и так — разницы особой нет.
Твой вариант с оставлением адреса — он как бе удобен, т.к. можно будет «поправить» адрес. Трабл только в том, что в блогах вручную редко набирают страницы — если только дело не касается поддоменов или чего-нибудь важного. Если ты пришел по ссылке, то тем более не станешь что-то исправлять — просто не знаешь, что именно :).
Во многих проектах это также бесмыссленно. Поисковик, конечно, поймет все и сольет страницы вместе, но иногда нужно иметь одну единственную 404. А для удобства можно и выводить запрошенный урл текстом или даже ссылкой в ноиндексе.
Впрочем, главное — чтобы правильно отдавались заголовки. С включенным ЧПУ проблема будет всего лишь одна — когда запрашивают страницу с параметрами, чтобы не выдавалось 200. Вместо проверки на УРИ — делаем проверку на ис_404, и вместо хедера — обычный инклюд. Хотя сам понимаешь, на блогах сама 404 — редкость, не то что обращение вида ?cat=..., когда включен ЧПУ.
А уж оставлять или не оставлять строку адрес — это решение каждого (типа, да, на вкус, на цвет, на взгляд). Зависит от конкретики.
Объясните мне кто нибудь, как 404 http заголовок подделать под 200/ok ? в том же самом вордпресс
@Харьковский Веб-мастер: отдать в начале страницы 404.php хедер 200 с помощью php (
). Только ума не приложу, зачем это надо.честно говоря страница 404 нужна, и если есть возможность сделать ее забавной — здорово. Придумывайте, креативьте, удачи