Задать вопрос

Настройка 404 в битриксе?

Всем привет!

Сайт на битриксе. Проблема в следующем: 404 страница показывается только на страницах вида: site.ru/abrakadabra
А на site.ru/catalog/abrakadabra вместо 404 показывает содержимое site.ru/catalog, хотя в ChromeDevTools в заголовке 404-ая...
В корне лежит файл 404.php верно настроенный, пробовал добавить в init.php
AddEventHandler('main',   'OnEpilog',   '_Check404Error', 1);

function _Check404Error()
{
   if (defined('ERROR_404') && ERROR_404=='Y' && !defined('ADMIN_SECTION'))
   {
   GLOBAL $APPLICATION;
   $APPLICATION->RestartBuffer();
   include   $_SERVER['DOCUMENT_ROOT'].'/bitrix/templates/'.SITE_TEMPLATE_ID.'/header.php';
   require   ($_SERVER['DOCUMENT_ROOT'].'/404.php');
   include   $_SERVER['DOCUMENT_ROOT'].'/bitrix/templates/'.SITE_TEMPLATE_ID.'/footer.php';
   }
}

но это не помогло.
  • Вопрос задан
  • 26727 просмотров
Подписаться 4 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 3
MintTea
@MintTea
В общем и целом, проверка (defined('ERROR_404') && ERROR_404 == 'Y') не позволяет отловить возникновение 404 ошибки в обработчике. Я писал по этому поводу в техподдержку, они передали мой тикет в разработку. Это было в октябре. Пока они слоупочат, вы можете перенести проблемный компонент в свое пространство имен, найти, где в нем вызывается CHTTP::SetStatus и добавить после него нужную строку:
CHTTP::SetStatus('404 Not found');
defined('ERROR_404') or define('ERROR_404', 'Y');


Либо, вы можете сравнить $arResult, который передается в шаблон при заходе на /catalog/ и при заходе на /catalog/abrakadabra, и найти такое условие, которое позволило бы определять, что возникла ошибка. По-моему, там есть что-то с TEMPLATE_NAME. Тогда добавите в index.php в шаблоне примерно следующее:
if ($arResult['TEMPLATE_NAME'] !== 'index.php')
{
    defined('ERROR_404') or define('ERROR_404', 'Y');
}


Либо, если вы не хотите этого делать, вы можете модифицировать сам метод CHTTP::SetStatus, как-то так:
class CHTTP
{
    public static function SetStatus($status)
    {
        ... 
        if ($status === '404 Not found')
           defined('ERROR_404') or define('ERROR_404', 'Y');
    }
}

Но это не приветствуется битриксом, и будет слетать при каждом обновлении.
Ответ написан
vasilyev
@vasilyev
php, 1c-bitrix
Это очень больной вопрос Битрикса. Я в свое время, после прочтения этого топика, забил и сделал обработчик с LocalRedirect. В теле топика есть решение, которое позволяет и выставить 404 статус и сохранить URL в адресной строке, но тогда дважды подключается header.php темы, в моем случае это было неприемлимо.
Ответ написан
Комментировать
Logic87
@Logic87
Программист/администратор сайтов на 1С-Битрикс.
Добавьте этот код в /bitrix/php_interface/init.php
define("PREFIX_PATH_404", "/404.php");

AddEventHandler("main", "OnAfterEpilog", "Prefix_FunctionName");

function Prefix_FunctionName() {
    global $APPLICATION;

    // Check if we need to show the content of the 404 page
    if (!defined('ERROR_404') || ERROR_404 != 'Y') {
        return;
    }

    // Display the 404 page unless it is already being displayed
    if ($APPLICATION->GetCurPage() != PREFIX_PATH_404) {
        header('X-Accel-Redirect: '.PREFIX_PATH_404);
        exit();
    }
}

Ваша 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("Страница не найдена");
?>
<h1>Страница не найдена</h1><br>
<p>Вы набрали неправильный адрес страницы. Пожалуйста, перейдите на главную страницу сайта или воспользуйтесь формой поиска.</p>
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>

Для элементов каталога этого достаточно. Но для несуществующих разделов надо добавить еще в шаблон комплексного компонента Каталога /bitrix/templates/s1/components/bitrix/catalog/new_catalog/bitrix/catalog.section.list/.default/template.php после первой строчки:
if(!$arResult["VARIABLES"]["SECTION_ID"]){
CHTTP::SetStatus("404 Not Found");
@define("ERROR_404","Y");
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы