×

301 редирект страницы с адресом на кириллице

В вебмастере яндекса и search console гугла периодически находятся нерабочие ссылки на сайты. Если ссылающаяся страница находится на моём сайте, то проблем нет – исправил и забыл. Если ссылка нашлась на внешнем сайте, то исправить её уже не получится.

Описание проблемы

Казалось бы: ну висят на каких-то непонятных сайтах кривые ссылки – нам то какая разница? Не всё так просто! Оказывается, у поисковиков есть отдельные санкции для сайтов с большим количеством ссылок возвращающих не 200 код ответа или просто неработающих.

Чтобы исправить эту проблему можно воспользоваться редиректами – они перенаправят запросы на кривые адреса на правильные страницы. Проще всего перенаправления делать в Apache. Для этого достаточно записать в файл .htaccess вот такую строку:


RedirectMatch permanent /кривая/ссылка/ /правильная/ссылка/

Либо воспользоваться модулем mod_rewrite, но это немного посложнее и не является темой этой записи.

Тем, кто пользуется nginx также можно написать в конфиг файл подобное правило:


rewrite /кривая/ссылка/ /правильная/ссылка/ permanent;

С обычными ссылками такие редиректы работают без проблем. Проблемы возникают с кириллическими ссылками — апач их просто не перенаправляет. Энджинкс редиректит только если в правиле используется кириллица. Punycode url (длинные ссылки с процентами) nginx перенаправлять на данный момент не умеет.

Также в nginx будут проблемы, если кривая ссылка была в пуникоде (который с процентами) и движок ссылающегося сайта обрубил её посередине. Такую ссылку невозможно будет корректно записать кириллицей и редирект работать не будет.

К тому же, на дешевых хостингах обычно нет доступа к конфигу nginx.

Решение проблемы

Раз апач и энджинкс нам не помогут, значит нужно решать проблему на другом уровне. После того как веб сервер передал данные к скриптам также имеется возможность сделать перенаправление. Ею мы и воспользуемся.

Мой блог работает на wordpress, в котором реализована удобная технология хуков. Она позволяет решить данную проблему. Добавлять хуки мы будем через файл functions.php, который находится в директории с текущей активной темой оформления. Нам понадобится хук на событие init. Это самое раннее подходящее событие, которое я смог найти.

Для перенаправления страницы создадим массив вида

['Текущий адрес' => 'Целевой адрес']

При каждом запросе будем искать в ключах этого массива содержимое элемента REQUEST_URI из суперглобального массива $_SERVER (это адрес страницы без домена сайта)

Если такой ключ имеется, будем делать permanent redirect, то есть постоянное перенаправление с 301 кодом. Этот код укажем во втором параметре функции wp_redirect.

Получаем вот такой код функции:


function wrongLinkRedirecting(){
   $arRedirects = [
      '/кривой/адрес' => '/правильный/адрес',
      '/кривойАдрес2/' => '/правильный/адрес/2/'
   ];
   
   if(isset($arRedirects[$_SERVER['REQUEST_URI']])){
      wp_redirect( $arRedirects[$_SERVER['REQUEST_URI']], 301 );
      exit();
   }
}
add_action( 'init', 'wrongLinkRedirecting' );

У себя на сайте я, на всякий случай, указывал две ссылки – в пуникоде и на кирилице. Так будет надёжнее.

Такой подход, конечно, расходует больше ресурсов сервера, чем редирект средствами apache или nginx, но в нашей ситуации это единственное средство, которое может помочь.

Проблема решена

P.S. красивее и экономнее было бы оформить это в виде must-use plugin’а. Тогда можно было бы использовать более раннее событие и не загружать лишний код до редиректа. Но этот код будет редко использоваться, поэтому такие оптимизации излишни.

logo