У меня есть сайт, который находится в корневой папке. Оно имеет .htaccess
с кодом ниже:
RewriteEngine on
RewriteRule ^(.*)/$ $1.php
Когда я открываю http://example.com/login/
Я получаю сообщение об ошибке «404 Not Found», но когда открываю http://example.com/login
без следа /
URL открывается без проблем.
я нуждаюсь .htaccess
код, который нужно установить в корневом каталоге, чтобы открыть файл PHP, например login.php
так как /login/
или /login
(без конечных /
).
Такое поведение типично для конфликта с MuiltiViews
. Вы должны отключить MultiViews в верхней части вашего .htaccess
файл:
Options -MultiViews
Это объясняет, почему /login
без следа /
успешно обслуживает файл - ваш RewriteRule
полностью игнорируется в этом сценарии.
При включенных MultiViews при запросе /login/
, mod_negotiation создает макет карты перезаписи и выдает внутренний подзапрос для /login.php
до того, как mod_rewrite обработает URL. Информация о пути (конечный /
) добавляется обратно, чтобы стать /login.php/
. Он передается для дальнейшей обработки и соответствует вашему слишком общему (^(.*)/$
) RewriteRule
шаблон, что привело к внутренней перезаписи на /login.php.php/
и т.д. В зависимости от вашей конфигурации это может привести к 403 (поскольку это может привести к искаженному запросу) или 404 (как вы, кажется, видите).
Отключение только MultiViews (как упоминалось выше) решит эту проблему. Однако вам также следует подумать о том, чтобы RewriteRule
шаблон более спокойный. Например, чтобы избежать совпадения URL-адресов, которые уже содержат точку (т. Е. Имеют расширение файла):
RewriteRule ^([^.]+)/$ $1.php [L]
Если просто сделать регулярное выражение более строгим, это может даже «исправить» ошибку. Однако это будут MultiViews, выполняющие внутренний подзапрос, а не mod_rewrite (ваше правило просто будет обойдено).
так как
/login/
или/login
(с завершающим/
)
Чтобы правило могло работать с /login/
или /login
(то есть с косой чертой в конце или без) вам нужно будет сделать конечную косую черту необязательной, т.е. /?
. Но вам также нужно будет либо сделать предыдущий шаблон не жадным, либо включить косую черту в класс инвертируемых символов, чтобы избежать захвата конечной косой черты в обратной ссылке.
Например, либо:
RewriteRule ^([^.]+?)/?$ $1.php [L]
Или,
RewriteRule ^([^./]+)/?$ $1.php [L]
Но второе правило будет работать только с URL-адресами, содержащими один сегмент пути, тогда как первое будет работать с URL-адресом формы /foo/bar/login
.
Options -MultiViews
RewriteEngine On
RewriteRule ^([^.]+?)/?$ $1.php [L]
Пытаться ^([^/]+)/?$
и посмотрите, работает ли он так, как ожидалось.