- Регистрация
- 30 Сен 2025
- Сообщения
- 38
- Реакции
- 12
- Баллы
- 8
О чем тред?
Это моя небольшая история о том, как забытые редиректы и один хитрый JS-виджет чуть не сожрали краулинговый бюджет форума — и что мы в итоге с этим сделали. Весь путь от диагностики до рабочих правил прошли в связке с Claude (ИИ-ассистентом от Anthropic) — он генерировал и объяснял варианты, а тестировал и правил код я уже сам. Так что где-то в тексте будут честные пометки "сработало" и "сгенерировано, но не проверено".Предыстория
Этот форум существует с 2008 года. К моменту покупки он много лет простоял без модерации, обзавёлся кучей чернухи и в какой-то момент угодил под блокировку РКН. Первым делом после покупки мы переехали с vBulletin на XenForo. Затем пару недель ушло на чистку контента, после чего отправили через официальный сайт РКН запрос на разблокировку домена — разблокировки ждали больше месяца. И увы, мы с коллегой забыли настроить редиректы, а когда вспомнили спустя время глянув консоли поисковиков, то решили что старые адреса видаshowthread.php?t=... сами по себе выпадут из индекса, а потому и не настраивали редиректы со старых URL на новые. Как оказалось, очень зря.Прошло около года с момента портирования
Несколько дней назад зашел в Яндекс Вебмастер и обнаружил, что он всё это время исправно обходил старые/showthread.php? — и каждый раз получал 404, но продолжал держать эти адреса в поле зрения. Стало ясно, что без явного сигнала (редирект или чёткое "удалено навсегда") эта история сама себя не решит, либо понадобятся годы на вылет старых URL из индекса.Развилка: редиректы или просто снести всё через robots.txt
Я с Claude рассматривал два варианта:- закрыть
/showthread.php?в robots.txt + вручную зачистить через инструмент удаления по префиксу в Яндекс.Вебмастере; - настроить честные 301-редиректы на новые адреса.
Выбрали редиректы — они ведь не просто убирают мусор из индекса, а ещё и сохраняют вес и трафик по тредам, которые до сих пор физически пережили миграцию. Плюс важный нюанс: инструмент «удаление по префиксу» в Яндекс.Вебмастере реально работает только для страниц, уже закрытых через Disallow — так что для части адресов, которые всё ещё редиректят на живой контент, весь префикс закрывать нельзя, иначе это сломает сами редиректы.
Первая проверка: сохранились ли ID при импорте
Тут стоит сразу сказать: у XenForo есть официальный бесплатный аддон именно под эту задачу — он строит редиректы со старых vBulletin-адресов на новые на основе данных, собранных прямо во время импорта. Но для его скачивания нужна активная лицензия XenForo. Если она у вас есть — это самый простой путь, ставьте аддон и не читайте дальше этот раздел.У нас с коллегой была только одна лицензия на несколько форумов, а к текущему моменту уже закончилась, поэтому покупать новую только ради одного аддона не имело бы смысла (тем более ни один из форумов не приносит прибыль) — поэтому пришлось искать бесплатный обходной путь, который описан ниже. Конечно существуют ещё форумы, который хранят бесплатные копии аддонов, но на проверенном и авторитетном русском форуме по Xenforo у нас нет прав на скачивание, а тратить на статус "проверенный" лишние 10 баксов совсем не хотелось. На иные форумы без репутации я бы не рисковал ходить, а то мало ли что там зашито в аддонах. Я однажды так уже попадал на проблемы, когда понадеялся на честность админов. Не знаю по какой причине, но в аддоне было захардкорено удаление сразу целого треда при изменении его рейтинга (аддон вводил рейтинг треда), при чем цепляло даже несколько рандомных тредов... Кстати, ситуацию тогда спас всё тот же Claude Code, который прошерстил все файлы аддона и нашел все его проблемы, после чего удалил зловредный код и переписал часть кода. Так что если и качаете, то дайте файлы аддона на проверку нейросетям. Но вернемся к редиректам. Если вы оказались в похожей ситуации, когда лицензии нет или она истекла, а рисковать не хочется, то вот что сработало у меня.
Ключевое условие для того, чтобы редиректы вообще имели смысл — совпадение числовых ID тредов/постов между старой vBulletin-базой и новой XenForo. Проверяется быстро: берёшь через Wayback Machine архивную версию
showthread.php?t=XXXXX, смотришь, какой был тред, и сверяешь с тем, что сейчас открывается по адресу /threads/XXXXX/ — у XenForo есть встроенный механизм, который резолвит тред по одному числовому ID, независимо от текстового slug в адресе.У меня все ID совпали, что стало большой удачей, потому что это сразу избавило от необходимости городить PHP-скрипт с таблицей соответствий или искать на сторонних ресурсах официальный аддон для восстановления связей.
Правила редиректов
Финальный рабочий набор для.htaccess покрывает следующие паттерны из vBulletin:showthread.php?t=ID→/threads/ID/showthread.php?p=ID(иshowpost.php?p=ID) →/posts/ID/printthread.php?t=ID→/threads/ID/forumdisplay.php?f=ID(с пагинацией и без) →/forums/ID/и/forums/ID/page-N/
Эти правила нужно прописывать после RewriteEngine On
Код:
# Редирект сообщений vBulletin (p=50111) в XenForo
RewriteCond %{QUERY_STRING} (?:^|&)p=([0-9]+) [NC]
RewriteRule ^showthread\.php$ /posts/%1/? [R=301,L]
# Редирект тем vBulletin (t=17002) в XenForo
RewriteCond %{QUERY_STRING} (?:^|&)t=([0-9]+) [NC]
RewriteRule ^showthread\.php$ /threads/%1/? [R=301,L]
# Редирект отдельных постов vBulletin (showpost.php?p=61253) в XenForo
RewriteCond %{QUERY_STRING} (?:^|&)p=([0-9]+) [NC]
RewriteRule ^showpost\.php$ /posts/%1/? [R=301,L]
RewriteCond %{QUERY_STRING} (?:^|&)t=([0-9]+) [NC]
RewriteRule ^printthread\.php$ /threads/%1/? [R=301,L]
# forumdisplay.php с номером страницы
RewriteCond %{QUERY_STRING} (?:^|&)f=([0-9]+) [NC]
RewriteCond %{QUERY_STRING} (?:^|&)page=([0-9]+) [NC]
RewriteRule ^forumdisplay\.php$ /forums/%1/page-%2? [R=301,L]
# forumdisplay.php без номера страницы (первая страница)
RewriteCond %{QUERY_STRING} (?:^|&)f=([0-9]+) [NC]
RewriteRule ^forumdisplay\.php$ /forums/%1/? [R=301,L]
Пара грабель по пути:
- Первая версия правил ловила
p=через жёсткий якорь$в конце регулярки — работало, пока в ссылке не появлялся третий параметр вроде&postcount=40. Без якоря на конце всё встало на место, порядок параметров в query string перестал иметь значение. - В правилах, где может быть и
t=, иp=одновременно (переход на конкретный пост в треде) — важен порядок условий: сначала проверяемp=, потомt=, иначе ссылка на конкретный пост скатывается на начало треда. - В какой-то момент показалось, что сайт стоит на nginx (заголовок
Server:в ответе так и показывал), и что весь.htaccessиз-за этого попросту не читается. Оказалось, что это был ложный след из-за проксирования форума — сам сервер как был на Apache, так и остался,.htaccessвсё это время исправно работал. Мораль: еслиcurl -Iпоказывает неожиданныйServer:, не спешите переписывать всё под другой веб-сервер — сначала проверьте, нет ли между вами и бэкендом прокси/защиты, которая подменяет заголовки.
Чеклист, если у вас похожая ситуация
1. ПроверьтеServer: в ответе сервера, прежде чем писать правила — Apache и nginx решают это по-разному.2. Проверьте, сохранились ли числовые ID при импорте — от этого зависит, можно ли обойтись простыми правилами или нужна таблица соответствий. Есть два пути:
- Сначала загляните в базу — если в ней уцелела служебная таблица лога импорта (у официального XenForo importer это, как правило,
xf_import_log с парами content_type / old_id / new_id), это готовое и точное соответствие, никакая ручная сверка не понадобится.- Если лог не сохранился — тогда вручную, через Wayback Machine: берёте архивную версию старого адреса, смотрите, какой там был контент, и сверяете с тем, что сейчас открывается по новому адресу с тем же ID.
3. Собирайте полный список legacy-путей одним отчётом (404-диагностика в Яндекс.Вебмастере / Google Search Console), а не патчите по одной жалобе за раз. В Яндексе, например, можно выгружать целые таблицы, которые затем можно отправить на переобход страниц.