This is my goal:
/any-directory-or-subdirectory
should show the contents of /any-directory-or-subdirectory/index.html
/any-directory-or-subdirectory/
should redirect to /any-directory-or-subdirectory
(no trailing slash)/any-directory-or-subdirectory/index.html
should redirect to /any-directory-or-subdirectory
/any-directory-or-subdirectory/something.htm
l should show its own contents.I have this working on a specific directory perfectly:
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]
I need this to work on all subdirectories instead of a specific one and also for the same functions to work at the root of the site. I've tried a number of things to adapt this code to work like that but have not had any luck so far.
Вам не нужно явно устанавливать переменную среды (например, LOOP
), чтобы избежать цикла перенаправления. Для этой цели вы можете использовать собственный Apache REDIRECT_STATUS
. REDIRECT_STATUS
не устанавливается при первой обработке запроса и устанавливается на 200
(как в 200 OK) после первой успешной перезаписи.
Я бы также разместил ваши директивы так, чтобы внешние перенаправления выполняются в первую очередь, до внутренней перезаписи, так как они всегда должны выполняться в первую очередь.
Чтобы эта работа работала для любого каталога, вы можете установить шаблон регулярного выражения для имени каталога (или, скорее, полный 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 жестко кэшируются браузером, поэтому тестирование может быть проблематичным.