RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [NC,QSA,L]
RewriteRule ^((.*)/)?index.[(php)(htm)(html)] $1
[R=301,L]
... наличие обоих этих правил в каждом случае приводит к перезаписи корня.
Поскольку после того, как первое правило переписало запрос в index.php
, процесс перезаписи начинается заново, а второе правило затем удаляет все из URL.
Ваше второе правило неверно. Он не совпадает с тем, что, по вашему мнению, соответствует, и неоправданно совпадает с любым URL-путем. Вы заявили, что это должно соответствовать только документу индекса в корне.
[(php)(htm)(html)]
- Предполагается, что целью является сопоставление с любым из этих расширений файлов, но вместо этого оно соответствует одному символу: p
, h
, t
, m
или l
. Для совпадения php
, htm
или html
необходимо использовать чередование . Например: (php|htm|html)
или (php|html?)
. (?
делает l
необязательным во втором шаблоне.)
Эти директивы также находятся в неправильном порядке. Внешнее перенаправление должно быть до вашего фронт-контроллера.
@ Ответ Бенджамина в значительной степени находится на кнопке, за исключением условия (которое никогда не будет совпадать) и того, что оно должно идти вверху вашего .htaccess
файла.
Попробуйте вместо этого:
RewriteEngine On
RewriteBase /
# Remove /index.php from URL
RewriteCond %{THE_REQUEST} \s/index\.php
RewriteRule ^index\.php$ / [R=302,L]
# Front controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
Флаги QSA
или NC
не требовались при перезаписи.
Причина проверки по THE_REQUEST
в первом условии состоит в том, чтобы предотвратить цикл перенаправления (в некоторых ситуациях). THE_REQUEST
содержит заголовок Host
из исходного запроса и не изменяется после перезаписи URL.
Проверьте с помощью 302
(временные) перенаправления и измените его на 301
(постоянный), только когда вы уверены, что это работает нормально. 301s кэшируется браузером, поэтому тестирование может быть проблематичным. Как всегда, вы должны убедиться, что ваш кеш браузера очищен перед тестированием.