Добро пожаловать на сайт Bitrix Q&A, где вы можете задавать вопросы о программировании и разработке на Битрикс и получать быстрые и квалифицированные ответы от профессионалов!


Удаление trailing slash (редирект 301) для существующих страниц + 404 без редиректа для несуществующих

0 голосов

Добрый день.

Встала задача сделать следующий набор редиректов.

Необходимо установить редиректное правило согласно которому любая страница со слешем на конце URL’а должна отдавать 301 редирект на себя же, только без слеша.

Правило касательно слеша на конце URL не касается главной страницы, страниц, сгенерированных с помощью параметров фильтрации, несуществующих страниц (отдающих код 404).

Для статических страниц было добавлено правило в htaccess

 

 

   Options -Indexes
    ErrorDocument 404 /404.php

    <IfModule mod_rewrite.c>
            Options +FollowSymLinks
            RewriteEngine On

           RewriteCond %{HTTP_HOST} ^www\.(.*)$
           RewriteRule ^(.*)$ http://%1/$1 [L,R=301]

           RewriteCond %{ENV:REDIRECT_STATUS} 200
           RewriteRule .* - [L]

    #редиректим существующие статические страницы со слешем на без слеша

    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteCond %{REQUEST_URI} !^/bitrix/admin/(.*)
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [R=301,L]

    #отрезаем слеш у ссылок на директории
    RewriteCond %{REQUEST_URI} ^.*[^/]$
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}/index.php -f
    RewriteCond %{REQUEST_URI} !^/bitrix/admin/(.*)
    RewriteRule ^(.*)$ /$1/index.php [L]

            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-l
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_FILENAME} !/bitrix/urlrewrite.php$
            RewriteRule ^(.*)$ /bitrix/urlrewrite.php [L]
            RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
    </IfModule>

    <IfModule mod_dir.c>
            DirectorySlash Off
            DirectoryIndex index.php index.html
    </IfModule>

 

 



Данные правила позволяют для существующих разделов отдавать редирект

Например domain.tld/about-us/  ---> domain.tld/about-us

При этом, не существующие страницы редиректиться не будут и сразу отдадут 404.

domain.tld/about-us/sdsdsd/  - сразу 404 без редиректа на domain.tld/about-us/sdsdsd

Вопрос возникает, каким образом  настроить подобное поведение для виртуальных страниц.

domain.tld/catalog/apparatyi-nedorogie/ редирект-> domain.tld/catalog/apparatyi-nedorogie

При этом

domain.tld/catalog/apparatyi-nedorogie/ddsdv/

domain.tld/catalog/apparatyi/

domain.tld/item/samson-komple/ - (не существуют) - сразу 404, без редиректа 301

domain.tld/item/samson-komplekt/  (существует)-> domain.tld/item/samson-komplekt

И подобное для любых виртуальных страниц, не только для страниц из примера.

Страница 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");
    ?>

        <div class="wrap_nofind_search">
            <div class="top_nofind_search">
                <h2>404 Страница не найдена</h2>

                <p>Извините, запрошенная Вами страница не найдена</p>
            </div>

        </div>
 

Средствами htaccess не видно возможности настроить такой избирательный редирект, только включить его для всех виртуальных старниц (существующих и несуществующих) или выключить.

Полагаю, можно настроить подобное поведение средствами битрикса. Вопрос в том, как?

Содержимое urlrewrite.php https://pastebin.com/GgQn6EXP

спросил 13 Сен от аноним
редактировать 13 Сен

1 Ответ

0 голосов

Состояние виртуальных страниц (существует или нет) видно только из обслуживающего их компонента. Так что, видимо, где-то там и надо делать LocalRedirect, который позволяет 301 статус выдавать.

LocalRedirect(
 string url,
 bool skip_security_check=false,
 string status="302 Found"
);
ответил 14 Сен от root (21,010 баллов)

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

0 голосов
0 ответов
0 голосов
1 ответ
0 голосов
2 ответов
спросил 30 Июнь, 13 от Beet (160 баллов)
+1 голос
1 ответ
спросил 02 Март от devenge (320 баллов)
+1 голос
1 ответ
спросил 11 Июнь, 14 от bravchik (130 баллов)
Управление продуктом: аналитика, разработка, продвижение