htaccess Silent Redirect to Subdirectory: подкаталог, показывающий, когда нет завершающего символа '/' - PullRequest
5 голосов
/ 08 ноября 2011

Я выкопал все вокруг Google и StackOverflow, чтобы попытаться выяснить мою проблему, пробуя бесчисленные решения, но ничего не получилось.

Я ищу, чтобы переместить корневой веб-сайт основного домена намой сервер в подкаталог.То, что у меня есть в настоящее время для пути сервера к моему веб-корню:

/home/user/public_html/MyWebFilesHere

Что я ищу:

/home/user/public_html/subdir/MyWebfilesHere

Когда я захожу на mydomain.com, должно бытьхотя видимой разницы нет (т.е. «subdir» не виден после перенаправления).

К сожалению, я ограничен в том, чтобы делать это только с файлом .htaccess, так как я на общем хостинге и не имею доступа к Apacheконфигурационные файлы и тому подобное.: (

В моем .htaccess в public_html в настоящее время есть:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com$
RewriteCond %{REQUEST_URI} !^/subdir/
RewriteRule ^(.*)$ /subdir/$1 [L]

Это успешно перенаправляет все запросы в подкаталог, однако есть действительно странная проблема. Если я пойдуна

mydomain.com/Contact/

он прекрасно работает, перенаправляя запрос к пути / subdir / Contact /, но оставляя адресную строку в покое. Если я перейду к

mydomain.com/Contact

(обратите внимание на отсутствиеконечный символ '/') показывает, что в адресной строке отображается

mydomain.com/subdir/Contact/

, что не то, что я хочу, так как отображается "subdir".

Для рабочего примера на моемфактический сайт, попробуйте перейти на

colincwilliams.com/Contact/

по сравнению с

colincwilliams.com/Contact

У вас, ребята, есть какие-нибудь идеи о том, как заставить это работать беззвучно как с косой чертой, так и без нее?

Ответы [ 2 ]

7 голосов
/ 08 ноября 2011

Это, вероятно, происходит потому, что mod_dir (модуль, который автоматически перенаправляет браузер, если в запросе каталога отсутствует косая черта для той же вещи с косой чертой. См. Директиву DirectorySlashв mod_dir

Что происходит:

  1. Вы запрашиваете: mydomain.com/Contact
  2. mod_dir не касается этого, так как /Contact не являетсякаталог
  3. /Contact переписывается на /subdir/Contact и внутренне перенаправляется
  4. mod_dir видит, что /subdir/Contact является каталогом и отсутствует косая черта, так что перенаправляет браузер с на mydomain.com/subdir/Contact/
  5. Итак, в строке адреса вашего браузера есть / subdir /.

Вы можете добавить DirectorySlash off в свой .htaccessчтобы отключить mod_dir от перенаправления. Но если вы хотите, чтобы в каталогах были завершающие косые черты, вы можете добавить для него отдельное условие. Исходя из того, что у вас уже есть, мы можем расширить его до следующего:

RewriteEngine on

# Has a trailing slash, don't append one when rewriting
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com$
RewriteCond %{REQUEST_URI} !^/subdir/
RewriteCond %{THE_REQUEST} ./\ HTTP/1\.[01]$ [OR]
# OR if it's a file that ends with one of these extensions
RewriteCond %{REQUEST_URI} \.(php|html?|jpg|gif|css)$
RewriteRule ^(.*)$ /subdir/$1 [L]

# Missing trailing slash, append one
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com$
RewriteCond %{REQUEST_URI} !^/subdir/
RewriteCond %{THE_REQUEST} [^/]\ HTTP/1\.[01]$
# But only if it's not a file that ends with one of these extensions
RewriteCond %{REQUEST_URI} !\.(php|html?|jpg|gif|css)$
RewriteRule ^(.*)$ /subdir/$1/ [L]

Примечание: Я изменил !^/mydomain/ на !^/subdir/, рисЭто была опечатка, потому что без нее mod_rewrite зациклился бы внутри бесконечно (foo -> / subdir / foo -> / subdir / subdir / foo -> / subdir / subdir / subdir / foo и т. д.).Если я ошибся, вы можете изменить его обратно.

Редактировать: Смотрите мои добавления соответствия RewriteCond с \.(php|html?|jpg|gif|css).Это расширения файлов, которые передаются без добавления завершающих слешей.Вы можете добавлять / удалять в соответствии с вашими потребностями.

0 голосов
/ 12 августа 2015

Ответ Джона Линя очень помог мне определить причину проблемы в моей очень похожей установке. Для полноты изложения я приведу соответствующую информацию из своего ответа:

Это, вероятно, происходит потому, что mod_dir (модуль, который автоматически перенаправляет браузер, если в запросе каталога отсутствует конечная косая черта, к той же вещи с конечной косой чертой. См. Директиву DirectorySlash в mod_dir

Что происходит, это:

  1. Вы запрашиваете: mydomain.com/Contact
  2. mod_dir не касается этого, поскольку /Contact не является каталогом
  3. /Contact переписывается на /subdir/Contact и перенаправляется изнутри
  4. mod_dir видит, что /subdir/Contact является каталогом и отсутствует косая черта, поэтому он перенаправляет браузер на mydomain.com/subdir/Contact/
  5. Так что теперь в строке адреса вашего браузера есть / subdir /.

В моем случае запросы были перенаправлены на /subdir с несколькими исключениями, и я не хотел повторно включать DirectorySlash для каждого из этих исключений.

Позволяя RewriteEngine продолжать после первоначального перенаправления на /subdir, можно имитировать, что будет делать mod_dir, также принимая во внимание /subdir, прежде чем mod_dir увидит его.

RewriteEngine on

RewriteCond %{REQUEST_URI} !^/exception1|exception2|...
RewriteRule ^(.*)$ /subdir/$1

RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^subdir/(.*) $1/ [R,L]

Примечание. Возможно, вам следует соблюдать осторожность, чтобы RewriteEngine продолжал работу, если существуют дополнительные правила. Несоответствие второму правилу переходит к любым другим правилам, которые могут привести к другому результату.

Этого можно избежать, используя третье правило для остановки обработки RewriteEngine, если произошло перенаправление в /subdir:

RewriteCond %{REQUEST_URI} ^subdir
RewriteRule .* - [L]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...