index.html redirection while maintaining static index.html file with Apache mod_rewrite

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.html 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.

1
задан 24 August 2017 в 21:55
1 ответ

Вам не нужно явно устанавливать переменную среды (например, 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 жестко кэшируются браузером, поэтому тестирование может быть проблематичным.

0
ответ дан 4 December 2019 в 04:43

Теги

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