В битриксе 404 ошибка отрабатывается весьма специфически: неправильный адрес со статических страниц и разделов корректно перебрасывает на страницу 404.php, при этом, сохраняя неправильный URL в адресной строке браузера. То есть, все по SEO.
А вот если неправильный адрес начинается с раздела инфоблока или каталога, то сервер отдаст браузеру 404 статус страницы (и то, при определенных настройках инфоблока, о которых ниже), но 404 страницу не покажет, а покажет корневую страницу инфоблока, причем, иногда совсем другого инфоблока. Но, все-таки, сохранит неправильный URL в адресной строке.
В интернете данный вопрос поднимался не раз. Когда-то популярным решением была настройка в битрикс принудительного редиректа на 404 страницу.))) Перечитав изрядно статей, выполнив несколько найденных инструкций, желаемого результата добиться не удалось(((. Пришлось, вооружившись командой print backtrace, отловить негодяйскую 404 ошибку и заставить ее работать, как положено.
Ставим задачу:
- Нужно, чтобы инфоблоки и каталоги в случае неправильной ссылки отдавали 404 статус.
- Нужно, чтобы этот статус правильно обрабатывался и приводил к вызову страницы 404.php.
На что стоит обратить внимание?
- Файл 404.php лежит в корне сайта. Должен выглядеть вот так (тут все стандартно):
<? if ($_SERVER['DOCUMENT_URI'] == "/404.php") { $_SERVER['REQUEST_URI'] = $_SERVER['DOCUMENT_URI']; } include_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/urlrewrite.php'); CHTTP::SetStatus('404 Not Found'); @define('ERROR_404', 'Y'); require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php"); $APPLICATION->SetTitle("Страница не найдена"); ?> ТУТ ТЕКСТ ВСЯКИЙ <? require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>
- В .htaccess должна быть вот такая строчка:
ErrorDocument 404 /404.php
Если у вас сервер на nginx, то нужно прописать в конфиге, в секции location, следующее:
error_page 404 = /404.php;
Тех. отступление:
Попробуем симулировать 404 ошибку с какой-нибудь статической страницы и отловить результат через команду debug_print_backtrace();
Смотрим файл, видим там строку с инклюдом 404 страницы. Она вызывается, очевидно, в том случае, если страница не найдена в структуре файлов и папок, а также в файле urlrewrite.php в корне сайта, где как раз описаны все наши инфоблоки и каталоги (для правильной работы ЧПУ).
Первая поставленная нами задача выполняется настройкой инфоблоков и компонентов.
- Проверим настройки самих каталогов:
URL страницы ИБ — должен указывать на папку, из которой будет осуществляться вызов инфоблока.
URL страницы раздела — если структура инфоблока будет иметь подразделы, то ссылка должна строиться на основе символьного кода раздела.
URL страницы детального просмотра — если элемент находится в подразделе, то к ссылке будет прибавляться символьный код раздела перед символьным кодом элемента. Иначе — только символьный код элемента.
- И инфоблоков:
То есть, как мы видим, для инфоблоков подразделы можно не описывать.
- Проверяем настройки вызова инфоблоков:
Обязательно проверяем, что отмечена галка «Включить поддержку ЧПУ»!
Каталог ЧПУ — корневая папка инфоблока.
Раздел — #SECTION_CODE#/ — повторяем из настроек инфоблока, но не ставим слеш в начале, иначе компонент будет работать неверно.
Детальная информация — #SECTION_CODE#/#ELEMENT_CODE#/ — ссылка формируется на основе символьного кода раздела (если есть) и кода элемента. Опять же, слеш в начале не ставим!
Если предполагается, что все элементы будут располагаться в корне инфоблока, без подразделов, то можно использовать следующие настройки:
То есть, поле для страницы раздела вообще можем пропустить, для страницы элемента: #ELEMENT_CODE#/ . Не забываем пропустить слеш в начале!
- Отмечаем галочку там же в настройках: «Устанавливать статус 404, если не найдены элемент или раздел:».
Тех. отступление:
После сохранения всех настроек, если мы набираем в разделе инфоблока неправильный адрес, то по-прежнему вместо 404 страницы увидим корневую страницу раздела инфоблока, но страница будет иметь в заголовке 404 статус. Посмотреть его можно через браузерную панель разработчика:
Этим мы и воспользуемся, а чтобы данный статус правильно обрабатывался
- Добавим следующий код в файл /bitrix/php_interface/init.php:
<? AddEventHandler('main', 'OnEpilog', '_Check404Error', 1); function _Check404Error(){ if (defined('ERROR_404') && ERROR_404 == 'Y') { global $APPLICATION; $APPLICATION->RestartBuffer(); include $_SERVER['DOCUMENT_ROOT'] . SITE_TEMPLATE_PATH . '/header.php'; include $_SERVER['DOCUMENT_ROOT'] . '/404.php'; include $_SERVER['DOCUMENT_ROOT'] . SITE_TEMPLATE_PATH . '/footer.php'; } } ?>
С этого момента страница ошибок будет работать! (наверное))) Если нет, опишите вашу ситуацию в комментариях.
UPD от 29.08.15: чуть обновил код файла 404.php и сниппет для init.php.
UPD от 15.01.18: настраивал сегодня на одном проекте отладку 404-й ошибки по данной инструкции. Все работает отлично)) Версия битрикса — последняя на указанную дату.
27 комментариев к “Не работает 404 ошибка в 1C-Битрикс. Правильная настройка”
Здравствуйте, Роман!
Сделал все как Вы описали, но некоторые страницы все равно выдают страницу 404, но статус 200
И наоборот статус 404 а страницу 404 не выдают
Куда копнуть, подскажите)
Евгений, внес пару правок в код, попробуйте у себя на проекте обновить
Роман, большое спасибо! Все заработало!!!!!!!
Роман, теперь почти все адреса обрабатывает правильно за исключением обработки адреса без «/» на конце и если к адресу дописать например .html. В этом случае статус 404, а страницу все равно не выдает((((
Буду очень благодарен если подскажете)
Евгений, простите за поздний ответ. Я делал переадресацию всех адресов без «/» на адреса со «/» на конце. Вот что касается .html, тут так сразу не подскажу.
Роман, спасибо за статью!
Сделал по Вашим инструкциям, но несуществующие страницы выдают страницу 404, но статус 200.
Можете подсказать в чём проблема?
Геннадий, здравствуйте! Сайт — который вы указали? У меня в некоторых разделах даже 404 страницу не отдает, вот пример:
http://laseroconcept.ru/services/meditsinskie-programmy/%D0%B2%D1%8B%D0%BF%D0%B2%D0%B0%D0%B0%D1%8B%D0%B2%D0%B2%D1%86 — просто пустая страница и статус 200
Проверьте, еще раз все настройки, особенно настройки для инфоблоков.
Роман, спасибо за ответ!
Роман, у меня не работает, сделал все один в один.
не правильный урл отсылает на корневую папку…
но в чпу у меня
Включить поддержку ЧПУ:
Каталог ЧПУ (относительно корня сайта): /catalog/brend/
Список разделов:
Раздел: #SECTION_ID#/
Детальная информация: #SECTION_ID#/#ELEMENT_ID#/
Таблица сравнения: compare/
как-то можно сделать?
Сделала, все несуществующие страницы + страницы несуществующих разделов и элементов ИБ отдают 500
А в логах что пишут?
/bitrix/php_interface/init.php
Не нашел файл, указанный файл ваш метод понял, но указанного файла я не нашел
Если этого файла нет, то его можно просто создать самому
С этим я разобрался но правильную переадресацию не всех урлов делает
Допустим Эти для инфоблоков он это делает, а для других отличных он это не делает
Если для каких-то инфоблоков способ сработал, то по логике должен сработать и для всех остальных. Нужно проверять настройки инфоблоков
У нас 404 ошибка не отрабатывает только для адресов типа site.ru/любой_текст
В какую сторону смотреть?
Павел, попробуйте, добавить в корневой файл index.php где-нибудь ближе к концу файла следующий код:
debug_print_backtrace();
И после этого откройте неправильный адрес в браузере типа site.ru/любой_текст и посмотреть, что выведется на экран.
не сработало
Спасибо, настроил согласно инструкций и всё ок!
Александр, рад, что вам помогло!
На двух сайтах всё получилось. На третьем не хочет. Настройки везде одинаковые, но третий сайт отдает 200 вместо 404 по левым урлам. Всё облазил. Непонятно, в чем вообще может быть проблема: галочки все стоят, пути прописаны, но реакции ноль. Это точно не кеш (чистил). Версия 14.5.1. Есть идеи, что может быть не так? Статические страницы отдают 404, всё, что связано с инфоблоками — 200.
Здравствуйте! Возможно, используются какие-то дополнительные компоненты из маркетплейса? Или дополнительные кастомизации. Чем-то же должен этот сайт отличаться от двух других))) Не хватает входных данных, чтобы сделать какое-то предположение
У меня файла init.php не был. Создал — перестал работать сайт
Валерий, здравствуйте! Очень странно, что его не было, он идет по умолчанию. Если после создания перестал работать сайт, вам нужно открыть файл /bitrix/.settings.php и там найти параметр «debug», указать для него значение «true», после этого обновить страницу сайта — появятся сообщения о том, где конкретно находится ошибка.
Статья помогла, спасибо большое!
А как сделать чтобы отдавалась 404 ошибка при обращении к несуществующему адресу каталога вида /каталог/категория/подкатегория/
Сейчас если добавляешь в урл */подкатегория/ то не отдает 404.
Весь каталог имеет вид урл /каталог/категория/товар.html
Спасибо огромное! Добавил обработчик в init.php и всё заработало!