Firwat funktionnéiert 301 Redirect net nom Ewechhuele vun .PHP Extensioun iwwer HTACCESS?

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:

  • net .php Versioun vun de Säite sinn net 301 Viruleedung.
  • béid . 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]
1
задан 10 June 2019 в 01:18
1 ответ

Я бы ожидал, что ваш код создаст цикл перенаправления вместо того, чтобы «не выполнять 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 преобразуется в /courses/blue-course.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 в родительской конфигурации ( каталог контекст).

0
ответ дан 4 December 2019 в 02:57

Теги

Похожие вопросы