Это моя цель:
/any-directory-or-subdirectory
должен показать содержимое /any-directory-or-subdirectory/index.html
/any-directory-or-subdirectory/
следует перенаправить на /any-directory-or-subdirectory
(без косой черты)/any-directory-or-subdirectory/index.html
следует перенаправить на /any-directory-or-subdirectory
/any-directory-or-subdirectory/something.htm
Я должен показать свое собственное содержимое.У меня это отлично работает с конкретным каталогом:
DirectorySlash Off
RewriteEngine on
RewriteRule ^specific-dir$ /specific-dir/index.html [L,E=LOOP:1]
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^specific-dir/$ /specific-dir [R=301,L]
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^specific-dir/index.html$ /specific-dir [R=301,L]
Мне нужно, чтобы это работало во всех подкаталогах вместо определенного, а также для того, чтобы те же функции работали в корне сайта. Я пробовал несколько вещей, чтобы адаптировать этот код для такой работы, но пока мне не повезло.
Вам не нужно явно устанавливать переменную среды (например, LOOP
), чтобы избежать цикла перенаправления. Вы можете использовать собственный Apache REDIRECT_STATUS
для этого. REDIRECT_STATUS
не устанавливается при первой обработке запроса и имеет значение 200
(как в 200 ОК) после первой удачной перезаписи.
Я бы также расположил ваши директивы так, чтобы внешние перенаправления выполнялись первыми, до внутренней перезаписи, поскольку они всегда должны выполняться первыми.
Чтобы это работало для любого каталога, вы можете установить шаблон регулярного выражения для имени каталога (или, скорее, полный URL-путь при работе с любым уровнем подкаталога) и включить условие, которое проверяет, сопоставляется ли запрос с каталогом. Например, попробуйте что-то вроде следующего:
DirectorySlash Off
RewriteEngine on
# Strip trailing slash on directory
# (The root always has a slash, but the browser doesn't show it)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.+)/$ /$1 [R,L]
# Strip trailing "/index.html" (including root)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*?)/?index\.html$ /$1 [R,L]
# Rewrite directory request to directory index
# (Any directory will already have had the trailing slash and "index.html" removed)
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*) /$1/index.html [L]
(.*?)/?index\.html$
- Сделав захваченную группу нежадной (т.е. (.*?)
), он не захватит по желанию слэш, следующий за ним. Если бы это было так, то можно было бы скопировать конечную косую черту в замена и приведет к дополнительному перенаправлению (поскольку первое правило позже удалит его). И сделав все до index.html
необязательно, он будет работать и для корня документа.
Измените временные (302) перенаправления на постоянные (301), только если вы уверены, что все работает нормально. 301 по умолчанию жестко кэшируются браузером, поэтому тестирование может быть проблематичным.