Ech läschen d'Erweiderung .php
aus Dateien aus engem spezifesche Verzeechnes op menger Websäit ( Coursen
]) iwwer .htaccess
op Apache / 2.2.26 (Unix).
Zousätzlech wéilt ech déi al .php
Versioun op net-php Versioun ëmleeden.
Al URL Struktur:
http://www.example.com/courses/blue-course.php
Nei URL Struktur:
http://www.example.com/courses/blue-course
Meng Aktuell Ausgaben:
.php
Versioun vun de Säite sinn net 301 Viruleedung. . php
an net .php
Versioune vun de Säiten sinn ze gesinn. Hei ass mäi Code:
RewriteEngine On
# External Routing
RewriteCond %{REQUEST_URI} (.*\/courses\/)([^\s]+)\.php [NC]
RewriteRule (.*courses\/)([^\s]+)\.php http://www.example.com/$1$2 [L,R=301]
# Internal Routing
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [L]
Я бы ожидал, что ваш код создаст цикл перенаправления вместо того, чтобы «не выполнять 301 перенаправление». Поскольку более раннее перенаправление также перехватывает перезаписанный URL (более поздней директивой) и перенаправляет и т. Д. И т. Д.
не
.php
версия страниц не является перенаправлением 301.
Не что правильно? Или здесь следует удалить «не» или «не»?
доступны для просмотра как
.php
, так и не.php
версии страниц.
предположить, что возможно включен MultiViews. Для правильного выполнения директив mod_rewrite необходимо отключить MultiView. (Здесь вы либо используете MultiViews , либо mod_rewrite, однако у вас могут возникнуть проблемы с попыткой перенаправить , если MultiViews включен.) Чтобы гарантировать, что MultiViews отключен, добавьте следующее вверху вашего .htaccess
файл:
Options -MultiViews
Однако, чтобы избежать цикла перенаправления, вместо сопоставления с REQUEST_URI
, который изменяется при перезаписи URL-адреса (то же, что и URL-путь, соответствует шаблону RewriteRule
), вы должны либо сопоставить с THE_REQUEST
(который содержит первую строку запроса и не изменяется), либо просто проверьте, что REDIRECT_STATUS
переменная среды пуста, чтобы гарантировать, что вы проверяете только начальный запрос, а не перезаписанный.
Например:
# External Routing
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*courses\/)([^\s]+)\.php http://www.example.com/$1$2 [L,R=301]
NB: Всегда тест с 302 (временными) перенаправлениями, чтобы избежать проблемы с кешированием.
Однако ваше регулярное выражение можно немного очистить. Согласно вашим примерам URL-адресов, / course
является первым сегментом пути, однако ваше регулярное выражение соответствует «course /» в любом месте URL-пути. И вы разрешаете перенаправление любого URL-адреса с информацией о пути - это намеренно? Вам нужна только одна обратная ссылка; не два. В шаблоне RewriteRule
нет необходимости экранировать слэши. Вам не обязательно нужна схема + имя хоста в строке подстановки , если у вас нет нескольких доменов?
Так что, возможно, это можно "упростить" до:
# External Routing
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(courses/[^\s]+)\.php$ /$1 [L,R=301]
# Внутренняя маршрутизация RewriteCond% {REQUEST_FILENAME} .php -f RewriteRule ^% {REQUEST_URI} .php [L]
Это может работать для конкретных URL-адресов, которые вы тестируете, однако это правило может легко нарушиться (и оно не нацелено конкретно на подкаталог / course
). % {REQUEST_FILENAME} .php
не обязательно совпадает с % {REQUEST_URI} .php
. Таким образом, хотя условие может быть успешным, вы все равно можете переписать его на недопустимый URL-адрес, что может привести к бесконечному циклу - 500 Internal Server Error.
Например, при запросе / course / blue- course / foo
(на основе вашего примера), где / course
- это каталог в файловой системе, а blue-course.php
- это файл, который вы собираетесь переписать (там не подкаталог / blue-course
), а / foo
- это просто что-то, что было ошибочно добавлено к URL-адресу (возможно, даже злонамеренно третьей стороной), тогда это приведет к ошибка 500. Поскольку % {REQUEST_FILENAME} .php
преобразуется в
(который существует), но % {REQUEST_URI} .php
] преобразуется в /courses/blue-course/foo.php
(которого не существует). Затем процесс перезаписи начинается заново, что приводит к бесконечному циклу.
Эту проблему можно решить, изменив правило на что-то вроде:
# Internal Routing
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule ^courses/ %{REQUEST_URI}.php [L]
Предполагая, что у вас нет нескольких расширений файлов или точек в базовом имени файла, например. blue-course.abc.php
, то это также можно оптимизировать, убедившись, что у запрошенного URL-адреса еще нет расширения файла (чтобы избежать проверки статических ресурсов). Например:
# Internal Routing
RewriteCond %{REQUEST_URI} !\.\w{2,4}$
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule ^courses/ %{REQUEST_URI}.php [L]
Префикс !
в CondPattern отрицает его значение.
Options -MultiViews
RewriteEngine On
# External Routing
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(courses/[^\s]+)\.php$ /$1 [L,R=301]
# Internal Routing
RewriteCond %{REQUEST_URI} !\.\w{2,4}$
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule ^ %{REQUEST_URI}.php [L]
Приведенные выше директивы предполагают, что вы используете .htaccess
в корневом каталоге документов вашего сайта. Однако, если вам нужно настроить таргетинг только на определенный каталог и у вас есть минимальное количество других директив mod_rewrite, которые вам нужно унаследовать от родительских конфигураций, может быть полезно создать дополнительный файл .htaccess
в этом подкаталоге, чтобы сохранить отдельную конфигурацию . Однако директивы необходимо немного изменить:
RewriteEngine On
# External Routing
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^([^\s]+)\.php$ /courses/$1 [L,R=301]
# Internal Routing
RewriteCond %{REQUEST_URI} !\.\w{2,4}$
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
RewriteRule ^ %{REQUEST_URI}.php [L]
Обратите внимание, что это (по умолчанию) полностью переопределит любые директивы mod_rewrite в родительской конфигурации ( каталог контекст).