Почему 301 редирект со слешем ведёт на другое зеркало и как это исправить

    При настройке перенаправления с URL, оканчивающегося на слеш, на версию без слеша, вы столкнулись с неожиданным результатом: запрос уходит на другое зеркало (site1.ru). Это типичная проблема, связанная с работой веб-сервера и правилами в файле .htaccess. В этой статье мы подробно разберём причины и предложим проверенное решение.

    Причина проблемы: конфликт правил и зеркал

    Ваш код в .htaccess:

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

    Этот блок корректно удаляет слеш в конце URL для запросов, которые не являются директориями. Однако, если на сервере настроены два зеркала (site1.ru и site2.ru), а в конфигурации Apache или в самом .htaccess прописаны дополнительные редиректы (например, для приведения домена к основному), то правило может срабатывать после того, как запрос уже был перенаправлен на site1.ru. Чаще всего это происходит из-за того, что редирект со слешем выполняется раньше, чем отрабатывает проверка домена, или наоборот - из-за некорректного порядка правил.

    Как исправить: пошаговая инструкция

    1. Проверьте порядок правил в .htaccess

    Убедитесь, что правило для удаления слеша находится до правил, которые перенаправляют site2.ru на site1.ru. Если сначала идёт редирект на основной домен, то запрос с /comments/ уже уходит на site1.ru, и ваше правило применяется к нему, но уже на другом домене. Правильный порядок:

    # 1. Удаляем слеш в конце
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} ^(.+)/$
    RewriteRule ^(.+)/$ /$1 [R=301,L]
    
    # 2. Редирект на основное зеркало (если необходимо)
    RewriteCond %{HTTP_HOST} ^site2\.ru$ [NC]
    RewriteRule ^(.*)$ https://site1.ru/$1 [R=301,L]

    2. Используйте абсолютный путь с доменом

    В правиле RewriteRule можно указать полный URL с доменом, чтобы избежать путаницы:

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} ^(.+)/$
    RewriteRule ^(.+)/$ https://site2.ru/$1 [R=301,L]

    Это гарантирует, что редирект останется на нужном зеркале.

    3. Проверьте настройки в конфигурации Apache

    Иногда проблема кроется в глобальных настройках сервера (httpd.conf или vhost-файлах). Если там прописан автоматический редирект со слешем на другой домен, ваш .htaccess может не успеть отработать. Рекомендуется временно отключить сторонние редиректы и протестировать.

    Альтернативное решение: редирект через mod_rewrite с проверкой домена

    Чтобы избежать конфликтов, можно добавить проверку текущего домена прямо в правило:

    RewriteCond %{HTTP_HOST} ^site2\.ru$ [NC]
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} ^(.+)/$
    RewriteRule ^(.+)/$ /$1 [R=301,L]

    Этот код сработает только для запросов к site2.ru, игнорируя site1.ru.

    Дополнительные советы

    • Очистите кэш браузера - старые 301 редиректы могли закэшироваться. Используйте режим инкогнито для тестирования.
    • Проверьте через curl: команда curl -I https://site2.ru/comments/ покажет цепочку редиректов.
    • Избегайте дублирования: убедитесь, что у вас нет других правил, которые также удаляют слеш.

    Часто задаваемые вопросы