Bitrix вернуть 404 ошибку

 

Здравствуйте.

На странице сайта выделяется часть УРЛ как символьный код элемента инфоблока. Сам инфоблок ищется вручную при помощи функции GetIBlockElementList(). Если эта функция возвращает false, то надо вернуть 404 ошибку.

Как ее вызвать ?

Подскажите, пожалуйста.

 

Пользователь 14571

Эксперт

Сообщений: 787
Баллов: 104
Регистрация: 10.08.2007

#2

0

03.04.2010 22:33:22

Код
<?php
header("HTTP/1.0 404 Not Found");
?>

или есть битрикс-API  функция для этого. Можно в мануале посмотреть.

мои проекты: https://blog.sokov.org/category/dhynedhdhudhnn/ | меня рекомендуют: https://blog.sokov.org/recommendations/ | обо мне: https://spb.hh.ru/resume/9f303161ff02e561e20039ed1f654846726333 | 1 час работы — 1200 руб.

 

CHTTP::SetStatus(«404 Not Found»);
@define(«ERROR_404″,»Y»);

Техдиректор — оперативная служба технической поддержки сайтов на Битриксе

 

Виталий
Евгений Неверов

Спасибо.

Но хочется сделать так, чтобы не только посылался заголовок ответа (404 Not Found), но показывалась вместо текущей страницы страница предназначенная для 404 ошибки.

Просто сейчас загружается страница с пустой контентной областью, а необходимо показать страницу предназначенную для 404 ошибки. Т.е. отменить вывод текущей страницы и вместо нее выдать страницу с описанием ошибки.

 

Редиректните тогда просто на страницу 404.php . Зачем вам тогда 404-я ошибка?

 

Пользователь 60679

Заглянувший

Сообщений: 7
Регистрация: 26.03.2010

#6

1

04.04.2010 11:29:17

Пока решил задачу таким образом:

Код
$item = $items->GetNext();
if (!$item)
{
   CHTTP::SetStatus("404 Not Found"); 
   @define("ERROR_404","Y");
   
   $rsSites = CSite::GetByID(SITE_ID);
   $arSite = $rsSites->Fetch();
   include($arSite['DOC_ROOT']."/404.php");
   return;
}

Оформил ввиде отдельной функции, которую залил в /bitrix/php_interface/ID_сайта/init.php

 

нормальное решение. :)

 

А вот интересно, можно ли как-то узнать, вызывалась ли команда CHTTP::SetStatus(«404 Not Found»); на странице ранее?

 

Пользователь 482727

Заглянувший

Сообщений: 7
Регистрация: 04.02.2016

#9

0

01.06.2016 16:03:56

Цитата
Евгений Неверов написал:
CHTTP::SetStatus(«404 Not Found»);
@define(«ERROR_404″,»Y»);

Походу за 6 лет чет изменилось? Не работает.
Есть идеи?

 

Пользователь 27542

Эксперт

Сообщений: 583
Баллов: 127
Регистрация: 28.07.2008

Какое еще пояснение?

#10

7

01.06.2016 16:35:12

Если нужно вызвать полностью 404 страницу с очисткой всего выведенного уже в рабочей области (а не только HTTP статус установить), то можно так:  

Код
if (!defined("ERROR_404"))
   define("ERROR_404", "Y");

\CHTTP::setStatus("404 Not Found");
   
if ($APPLICATION->RestartWorkarea()) {
   require(\Bitrix\Main\Application::getDocumentRoot()."/404.php");
   die();
}

 
 

компоненты, модули · адаптивный форум · свойства-таблицы

Есть инфоблок со списком поддоменов.
Если зайти на поддомен, которого нет в этом списке, должен отдаваться статус 404.

Нижеприведённый код работает на всём сайте, кроме главной страницы.
К примеру, a.vsesvetodiody.ru/dileram.html — правильно отдаёт 404, а просто a.vsesvetodiody.ru выдаёт пустую страницу, хотя скрипт точно доходит до создания файла 1111111111111111111.txt
В чём может быть проблема?

AddEventHandler("main", "OnEpilog", "handler404");
function handler404()
{
  
    global $USER;
    global $APPLICATION;
  
    $curDir = $APPLICATION->GetCurDir();
    $arDir = explode('/', $curDir);
    $curPage = $APPLICATION->GetCurPage();
    
    if (isset($_SERVER["REAL_FILE_PATH"]))
    {
        $arRequest = explode("/", $_SERVER["REDIRECT_URL"]);
        if  (
                (
                    ($_SERVER["REAL_FILE_PATH"] == "/index.php") 
                    && (count($arRequest) != 3)
                ) 
                || 
                (
                    (count($arRequest) == 3) 
                    && (strlen($arRequest[2]) > 0) 
                    && (substr($arRequest[2], -5, 5) != ".html")
                )
            )
        {
            define("ERROR_404", "Y");
        }
    }


    $poddomen=str_replace(".vsesvetodiody.ru","",$_SERVER["HTTP_HOST"]);
    $poddomen=str_replace("vsesvetodiody.ru","",$poddomen);
   
  
    if(defined('ERROR_404') && ERROR_404 == 'Y')
    {
    
        $template = 'main';
        $APPLICATION->RestartBuffer();
        $APPLICATION->SetPageProperty("title", "Ошибка 404");
        $APPLICATION->SetPageProperty("h1", "Error 404");
        $APPLICATION->SetTitle("Error 404");
        include_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/urlrewrite.php');
        include $_SERVER['DOCUMENT_ROOT'].'/bitrix/templates/'.$template.'/header.php';
        include $_SERVER['DOCUMENT_ROOT'].'/include/404_text.php';
        include $_SERVER['DOCUMENT_ROOT'].'/bitrix/templates/'.$template.'/footer.php';
    
    } else if ($poddomen) {

        CModule::IncludeModule('iblock');
        $select = Array("NAME","ID","CODE");
        $arFilter = Array("IBLOCK_ID"=>2, "CODE" => $poddomen, "ACTIVE" => "Y");
        $res = CIBlockElement::GetList(Array("SORT"=>"ASC", "PROPERTY_PRIORITY"=>"ASC"), $arFilter, $select);
        $poddomen = $res->GetNext();  

        if(!$poddomen["ID"])  {

          file_put_contents('1111111111111111111.txt', 1); 

          $template = 'main';
          $APPLICATION->RestartBuffer();
          $APPLICATION->SetPageProperty("title", "Ошибка 404");
          $APPLICATION->SetPageProperty("h1", "Error 404");
          $APPLICATION->SetTitle("Error 404");
          include_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/urlrewrite.php');
          include $_SERVER['DOCUMENT_ROOT'].'/bitrix/templates/'.$template.'/header.php';
          include $_SERVER['DOCUMENT_ROOT'].'/include/404_text.php';
          include $_SERVER['DOCUMENT_ROOT'].'/bitrix/templates/'.$template.'/footer.php';

        }

    }
  
}

Оглавление

  • Проверка сайта и настройка 404-й страницы
  • Ошибка элемент/раздел не найден
  • Оформляем 404-ю страницу

Вы наверняка сталкивались с проблемой когда при обращении к несуществующему адресу в каталоге товаров или в разделе новости, вместо 404-й страницы получали ответ «не найден раздел или элемент» при этом серверу в заголовка отдавался статутс 200 ok а не 404 not found. Это не правильно, т.к. поисковик может проиндексировать пустые страницы которые впоследствии повысят количество отказов при заходе реальных посетителей на сайт. И так почему так происходит и как этого избежать.

В первую очередь нам нужно проверить наличие некоторых фалов и настроек на сайте.

Во-первых проверим наличие файла 404.php который должен лежать в корне вашего сайта. Если его нет, можете его создать с таким содержимым:


<?
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("404 Not Found");
 
$APPLICATION->IncludeComponent("bitrix:main.map", ".default", Array(
	"LEVEL"	=>	"3",
	"COL_NUM"	=>	"2",
	"SHOW_DESCRIPTION"	=>	"Y",
	"SET_TITLE"	=>	"Y",
	"CACHE_TIME"	=>	"3600"
	)
);
 
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>

Ключевыми в этом файле являются строки:


<?
CHTTP::SetStatus("404 Not Found");
@define("ERROR_404", "Y");

Возможно у вас есть сам файл, но отсутствуют эти строки, что и приводит к ошибке в работе 404-й.

Во-вторых, проверьте файл .htaccess (если он поддерживается вашим сервером), в нём должна присутствовать такая директива:


ErrorDocument 404 /404.php

Теперь перейдите к настройкам вашего компонента (обычно это bitrix.catalog или bitrix.news), блоке «настройки 404 ошибки» отметьте галочку «Устанавливать статус 404» (название галочки может отличаться в компонентах, в некоторых она называется «Устанавливать статус 404, если не найдены элемент или раздел:»).
Настройка 404-й страницы
Затем в файл /bitrix/php_interface/init.php (или /local/php_interface/init.php) добавьте следующий код:


<?
AddEventHandler("main", "OnEpilog", "error_page");
function error_page()
{
	$page_404 = "/404.php";
	GLOBAL $APPLICATION;
	if(strpos($APPLICATION->GetCurPage(), $page_404) === false && defined("ERROR_404") && ERROR_404 == "Y")
	{
		$APPLICATION->RestartBuffer();
		CHTTP::SetStatus("404 Not Found");
		include($_SERVER["DOCUMENT_ROOT"].SITE_TEMPLATE_PATH."/header.php");
		include($_SERVER["DOCUMENT_ROOT"].$page_404);
		include($_SERVER["DOCUMENT_ROOT"].SITE_TEMPLATE_PATH."/footer.php");
		die();
	}
}

Этим кодом, мы добавляем в OnEpilog свой обработчик события, который считывает установленный компонентом параметр ERROR_404 и запускает перегрузку буфера подключая файл 404-й страницы. Обычно это 404.php лежащий в корне сайта. Хотя при соответствующем оформлении 404-й страницы, можно (даже будет лучше) не подключать файлы header.php и footer.php.

Если после всех манипуляций 404-я страница не отображается по несуществующему URL, следует проверить файл urlrewrite.php отвечающий за обработку ЧПУ адресов. Иногда, например при размещении компонента умного фильтhа (catalog.smart.filter) на главной странице, в urlrewrite.php прописывается условие, что-то вроде этого:


<?
array(
    "CONDITION" => "#^/([a-zA-Z]+)/([0-9]+)/#",
    "RULE" => "",
    "ID" => "bitrix:catalog.section",
    "PATH" => "/index.php",
),

Обычно в CONDITION — создаётся некорректное регулярное выражение, которое срабатывает на все страницы, в том числе и на не существующие и вместо 404-й страницы, сайт выдаёт что-то ещё, обычно страницу или компонент указанный в PATH этого правила. Если такое правило есть, его необходимо скорректировать или удалить из urlrewrite.php.

Ошибка элемент/раздел не найден

Такая ошибка возникает когда шаблоны ЧПУ в инфоблоке и в настройках компонента не совпадают. Или же пользователь ввёл некорректный URL близкий к шаблону. Проверьте настройки инфоблока:

Настройка ЧПУ в инфоблоке

И настройки ЧПУ в компоненте (обычно комплексном):

Настройка ЧПУ в комплексном компоненте

Так же следует проверить соответствие шаблона и свойств элемента. Например в примере в шаблон URL детальной страницы входит символьный код элемента #ELEMENT_CODE#, если у элемента нет символьного кода, вы получите ошибку. Но правильнее конечно, не показывать такие сообщения (элемент не найден, раздел не найден), компонент должен установить статус 404 и должен сработать скрипт показывающий пользователю /404.php с соответствующим ответом в заголовке. В противном случае, могут быть проблемы с SEO сайта.

Оформляем 404-ю страницу

По умолчанию 404.php в 1С Битрикс содержит компонент карты сайта и выводит список ссылок взятый из файлов формирования меню. При этом на странице так же остаётся полноценная шапка и подвал сайта (отрабатывают header.php и footer.php шаблона), что на мой взгляд не правильно. Кстати сеошники из компании Кокос, с которыми мне приходилось сталкиваться, так же не рекомендовали выводить шапку и подвал с полноценной навигацией по сайту на 404-й странице.

На мой взгляд 404-я должна говорить пользователю что он всё ещё на том же сайте где и был секунду назад,  отвечать на вопрос почему он здесь и что делать дальше и отдавать соответствующие заголовки поисковому роботу.

И так давайте выведем 404-ю страницу битрикс без шапки и подвала, но при этом подтянем ядро системы, чтобы мы могли подключить стили шаблона по средствам константы SITE_TEMPLATE_PATH. Убираем всё лишнее, подключаем ядро, получаем такой файл:


<?
//Подключаем ядро битрикса без шапки
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
//Устанавливаем необходимые заголовки
CHTTP::SetStatus("404 Not Found"); @define("ERROR_404","Y");


Чтобы посетитель не подумал что он покинул ваш сайт, стили оформления 404-й страницы должны быть такими же как и на всём сайте (заголовки, шрифты, цвета, иконки, картинки). Обязательно (минимально) на этой странице должен быть логотип.

Я люблю когда сообщения об ошибках читаются сразу, поэтому пишу их большими шрифтами, например Open Sans Condensed, не мельчите и объясняйте пользователю куда он попал и что ему дальше делать (вернуться на главную страницу, сделать запрос в форме поиска, в конце концов позвонить или написать вам). У меня получилась такая страничка:


<? require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); //Подключаем ядро битрикса без шапки CHTTP::SetStatus("404 Not Found"); //Устанавливаем необходимые заголовки @define("ERROR_404","Y");  ?>
<link href='https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300,300italic,700|Arimo:400,400italic,700,700italic|Noto+Sans:400,400italic,700,700italic&subset=latin,cyrillic-ext' rel='stylesheet' type='text/css'>

<div class="container404">
	<img src="<?=SITE_TEMPLATE_PATH;?>/images/logo.jpg" alt="Название сайта">
	<span class="title404">404</span>
	<span class="subtitle404">Страница не найдена</span>
	<span class="description404">Возможно запрашиваемая вами страница была удалена или перемещена. Вернуться <a rel="nofollow" href="/">на главную</a>?</span>
	<span class="contacts404">позвоните нам: <span class="phone404"> +7 (999) 000 - 00 - 00</span> или напишите на e-mail: <a target="_blank" href="mailto:example@mail.ru">example@mail.ru</a></span>
</div>

Добавим немного CSS стилей для полноты картины:


.container404 { text-align: center; width: 1200px; margin: 0 auto; margin-top: 100px;}
.container404 img { display: block; margin: 0 auto; margin-bottom: 50px; }
.container404 a { color: #F0A229; }
.container404 a:hover { text-decoration: none; }
.title404 { font-family: 'Open Sans Condensed', sans-serif; font-size: 60px; line-height: 80px; display: block; }
.subtitle404 { font-family: 'Open Sans Condensed', sans-serif; font-size: 40px; line-height: 60px; display: block; }
.description404 { font-family: 'Open Sans Condensed', sans-serif; font-size: 30px; line-height: 40px; display: block;}
.contacts404 { margin:0 auto; width: 800px; padding: 10px 0px 100px 0px; font-family: 'Open Sans Condensed', sans-serif; font-size: 30px; line-height: 40px; }
.phone404 { font-weight: bold; }

Вроде бы всё. Ах да чуть не забыл! Нужно проверить всё ли правильно отдаётся поисковому роботу. Для этого перейдите на сайт, вызовете консоль разработчика (обычно клавиша F12 или пункт в меню инструментов браузера «инструменты разработчика» или что-то подобное), перейдите на вкладку Сеть/Network введите адрес несуществующей страницы и посмотрите какой ответ вернёт сервер (вкладка Status):

Работа 404-й страницы

Как видите всё в порядке, сервер вернул 404-й заголовок, что означает — страница не существует, а следовательно поисковик не проиндексирует ненужные адреса и в поиск попадут только реально существующие документы вашего сайта. Теперь точно всё. Желаю удачи!

Очень часто сео-специалисты ставят задачу как можно сильнее упростить адрес до карточки товара и до карточки раздела и как результат мы получаем шаблон адреса вида: /раздел/  и /товар/. В таком случае типовой компонент catalog при включенном режиме отдачи 404-й ошибки, будет выдавать ошибку. Чтобы этого избежать, нужно вносить правки в логику отображения.

Для начала отключаем режим показа 404-й страницы в настройках компонента каталога.

Далее, открываем файл section.php каталога и тут настраиваем свой код определения того, какую страницу показывать — страницу товара или страницу раздела — проверяем по базе данных, если есть товар с заданным символьным кодом — показываем карточку товара. Если  товара нет, но есть раздел с таким символьным кодом — показываем его. Если же ни товара, ни раздела с заданным символьным кодом нет — нужно показать 404-ю страницу. Для этого можно воспользоваться следующим кодом:

if (!defined("ERROR_404"))
	define("ERROR_404", "Y");

\CHTTP::setStatus("404 Not Found");

if ($APPLICATION->RestartWorkarea())
{
	require(\Bitrix\Main\Application::getDocumentRoot() . "/404.php");
	die();
}

В результате пользователю будет показана 404-я страница. Адрес при этом не изменится.

2019-02-28. Решение, используемое в ядре системных компонентов:

Bitrix\Iblock\Component\Tools::process404(
       'Не найден', //Сообщение
       true, // Нужно ли определять 404-ю константу
       true, // Устанавливать ли статус
       true, // Показывать ли 404-ю страницу
       false // Ссылка на отличную от стандартной 404-ю
);

Типовой каркас 404-й страницы:

<?
	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("Страница не найдена");
	$APPLICATION->SetPageProperty("keywords", "Страница не найдена");
	$APPLICATION->SetPageProperty("description", "Страница не найдена");
	?>

<div class="container-error-page">
        <div class="error-page-big-text">
            404
        </div>
        <div class="col col-12 ta-center">
                <?$APPLICATION->IncludeComponent(
					"bitrix:search.form",
					"bottom",
					array(
						"COMPONENT_TEMPLATE" => "bottom",
						"PAGE" => SITE_DIR."search/index.php"
					),
					false
				);?>
            </div>

            <p>
                <a href="/">Главная страница</a>
            </p>
            <p>
                <a href="search/map.php">Карта сайта</a>
            </p>
 </div>

<? require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php"); ?>

24.09.2013

Компоненты Bitix, в случае, если требуемый элемент/раздел не найден не показывают страницу с 404 ошибкой. Они просто выводят текст ошибки и возвращают статус 404:

Элемент не найден!

Я считаю что это никуда не годится. Юзабилити тут даже и не пахнет. А как же показать пользователю стилизованную страницу, на которой направить пользователя на нужные страницы?

Благо делается это совсем просто, достаточно подготовить файл 404.php, который нужно разместить в корне. Это у вас скорее всего уже сделано, т.к. по умолчанию в .htaccess bitix’а указано что, если в структуре сайта запрашиваемый файл не найден — то возвращать /404.php

Далее в файле 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';
    }
}

Событие вызывается в момент когда страница уже сформировалась. Происходит проверка на ERROR_404 == «Y». Если проверка успешна, значит какой то из компонентов на странице вернул 404-ю ошибку. Очищаем буфер вывода $APPLICATION->RestartBuffer(); и подключаем визуальные файлы для отображения подготовленной 404 страницы.

Текст в компоненте

На случай написания своего компонента, приведу код, который нужно вызывать в компоненте при обнаружении 404-й ошибки:


if (!isset($arResult['SECTION'])){
    $this->AbortResultCache();
    @define('ERROR_404', 'Y');
    return;
}

Если искомый результат не найден, прерываем кеширование компонента, объявляем ERROR_404, выходим из компонента.

Типовой файл 404.php

Файл 404.php все же не совсем обычная страница, поэтому приведу заготовку:


<?require($_SERVER['DOCUMENT_ROOT'].'/bitrix/header.php');
CHTTP::SetStatus('404 Not Found');
@define('ERROR_404','Y');
$APPLICATION->SetTitle('Страница не найдена');?>
404
<?require($_SERVER['DOCUMENT_ROOT'].'/bitrix/footer.php');?>

Устанавливаем статус 404, объявляем ERROR_404(вдруг обратились напрямую к /404.php). В остальном это обычная текстовая страница bitrix.

Послесловие

Мне этот метод не нравится. Проблема в том, что после обнаружения 404-ошибки страница продолжает отрабатывать до конца, а затем этот напрасный труд очищается.

Как то на коленке я пробовал найти другое решение, проверил то, что пришло в голову, но не вышло, потом я на это забил. Возможно если подойти к вопросу обстоятельно то окажется что все просто и решение на поверхности, но пока как то не до этого. Да и кто смотрит на 404-ю?!

Если у вас есть более элегантное и менее ресурсозатратное решение — прошу в комментарии.

Понравилась статья? Поделить с друзьями:

Интересное по теме:

  • Bitrix веб формы ошибка доступ запрещен
  • Bitrix sphinx connect error ошибка подключения
  • Bitrix smart filter 404 ошибка
  • Bitrix env логи ошибок
  • Bioshockhd exe ошибка при запуске приложения

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии