.htaccess mod_rewrite ссылается на неправильную страницу
-
09-12-2019 - |
Вопрос
У меня в .htaccess есть следующий код:
RewriteEngine On
RewriteRule ^/?([^/\.]+)/?$ $1.php [L]
RewriteRule ^/?([^/\.]+).php$ $1/ [R,L]
RewriteRule ^/?([^/\.]+)/?$ $1.php [L]
работает нормально.Что это делает, это берет URL-адрес типа http://www.example.com/whatever
и заставить его прочитать страницу как http://www.example.com/whatever.php
.
Однако то, что я хотел бы сделать, это взять URL-адрес типа http://www.example.com/whatever.php
и автоматически отправить его на http://www.example.com/whatever
, отсюда и вторая строка кода.Однако это не работает.Сейчас он делает следующее: как только он встречает ссылку, оканчивающуюся на .php
, URL-адрес становится http://localhost/C:/Sites/page/whatever/
, и потянув 403: Forbidden
страница.
Все, что я хочу знать, это то, что я могу сделать, чтобы http://www.example.com/whatever.php
будет читаться как http://www.example.com/whatever
, и это если http://www.example.com/whatever.php
вводится в строку URL, он автоматически перенаправляется на http://www.example.com/whatever
.
Имеет ли это смысл?
РЕДАКТИРОВАТЬ
ОК, похоже, я не совсем ясно выразился..в общем, я хочу /whatever/
читать как whatever.php
в то время как URL-адрес по-прежнему остается прежним /whatever/
, верно?Однако если URL-адрес был /whatever.php
, я хочу, чтобы это на самом деле перенаправить URL-адрес пользователя, на который /whatever/
, а затем еще раз прочитайте его как whatever.php
.Это возможно?
Решение
Если ваши правила находятся внутри файла .htaccess, вы можете опустить косую черту при сопоставлении с URI:
RewriteRule ^([^/\.]+)/?$ /$1.php [L]
Также обратите внимание, что в цель включена ведущая косая черта (/$1.php
), это гарантирует /что бы ни/ перезаписывается на /что угодно.php.Если при перенаправлении вам не хватает этой косой черты, Apache добавляет к ней корень документа.Таким образом /что угодно.php перенаправляется в корень документа C:/Сайты/страница/что угодно/.Даже если вы добавите косую черту в начале, это никогда не сработает, потому что вы вызовете цикл перенаправления:
- Введите «http://www.example.com/whatever.php» в адресной строке.
- Apache перенаправляет вас на «http://www.example.com/whatever/»
- Apache получает URI что бы ни/ и применяет первое правило, и URI перезаписывается на /что угодно.php
- URI снова проходит через механизм перезаписи.
- URI /что угодно.php соответствует второму правилу и перенаправляет браузер на «http://www.example.com/whatever/»
- повторите шаги 3-5
Вам необходимо добавить условие, согласно которому фактический запрос для /что угодно.php:
RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /([^/\.]+)\.php
RewriteRule ^ /%2/ [R,L]
Итак, в целом у вас будет:
RewriteEngine On
RewriteRule ^([^/\.]+)/?$ /$1.php [L]
RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /([^/\.]+)\.php
RewriteRule ^ /%2/ [R,L]
Другие советы
Вы выполняете замену относительного пути в контексте каждого каталога (.htaccess
это контекст для каждого каталога).Это требует RewriteBase
.Перезапись для каждого каталога выполняется на более позднем этапе обработки, когда URL-адреса сопоставлены с путями.Но перезапись должна создать URL-адрес, который обрабатывается снова.Я думаю, что без RewriteBase
Чтобы указать префикс URL-адреса, вместо URL-адреса вы получите префикс файловой системы.Возможно, поэтому вы получаете C:/Sites
вещь.Пытаться RewriteBase
.Но после правильного RewriteBase
чтобы указать правильный префикс URL-адреса, который будет прикреплен перед относительной переписанной частью, боюсь, у вас возникнет цикл перезаписи, потому что вы переписываете whatever.php
к whatever
;и whatever
к whatever.php
.
Ссылка: http://httpd.apache.org/docs/current/rewrite/tech.html