Как сделать редирект на index.php без изменения URL в браузере
При разработке веб-проектов часто возникает задача: при обращении к site.ru/15 нужно отдать содержимое site.ru/15/index.php, но адресная строка должна остаться прежней - site.ru/15. Обычное правило mod_rewrite с флагом R (редирект) меняет URL, что не подходит. Разберём, как настроить внутренний редирект (субзапрос) без внешнего перенаправления.
Почему стандартный RewriteRule меняет URL?
Когда вы используете RewriteRule ^15$ /15/index.php [NS,L], Apache выполняет внутреннее перенаправление, но по умолчанию добавляет завершающий слеш к URL. Это связано с модулем mod_dir, который при обнаружении каталога /15/ автоматически добавляет слеш. В результате браузер показывает site.ru/15/, а не site.ru/15.
Как сохранить исходный URL: решение через флаг PT
Чтобы URL остался неизменным, необходимо отключить поведение mod_dir и использовать флаг PT (Pass Through). Этот флаг передаёт управление следующему обработчику, не изменяя запрос. Добавьте также DirectorySlash Off для отключения автоматического добавления слеша.
Пример правильной конфигурации в .htaccess
RewriteEngine On
DirectorySlash Off
RewriteRule ^15$ /15/index.php [PT,L]После этого при обращении к site.ru/15 сервер отдаст содержимое /15/index.php, а в адресной строке останется site.ru/15.
Дополнительные рекомендации
- Убедитесь, что файл
/15/index.phpсуществует, иначе сервер вернёт ошибку 404. - Если в каталоге
/15/есть другие файлы, флаг PT может повлиять на их обработку - проверьте логи. - Для сложных проектов используйте флаг
END(Apache 2.4+) вместоL, чтобы остановить все последующие перезаписи.
Альтернативный подход: использование FallbackResource
Если у вас Apache 2.2+, можно применить директиву FallbackResource в конфигурации виртуального хоста. Это более простой способ, но он менее гибкий для отдельных URL.
FallbackResource /15/index.phpЭтот метод подходит, если нужно перенаправлять все запросы к несуществующим файлам на один обработчик.
Проверка и отладка
После внесения изменений очистите кеш браузера и проверьте заголовки ответа. Используйте инструменты разработчика (вкладка Network), чтобы убедиться, что код ответа - 200, а не 301 или 302. Также проверьте URL в адресной строке: он должен остаться site.ru/15.