Таким образом, все внутренние ссылки должны иметь go - example.com/site/.*
Если вы хотите sh скрыть подкаталог /site
от URL-адреса, тогда вам нужно на самом деле удалите /site
сегмент URL-пути из всех ваших внутренних гиперссылок. Если в ссылке присутствует часть /site
, то все ваши пользователи могут видеть ее (на странице и в строке состояния - перед тем, как щелкнуть ссылку), поэтому она вообще не «скрыта».
- Никто не должен иметь доступ к базовому URL (
example.com
), и любой, кто пытается получить к нему доступ, должен быть перенаправлен на example.com/site/
- Принудительно использовать https для всех ссылок, включая URL-адреса в подпапках и подпапках.
- Скрыть
/site/
в отображаемом имени URL
№ 1 и № 3 являются противоречием. Вы не можете «перенаправить» на «/ site» (# 1) и скрыть сегмент /site
URL-пути (# 3). «Перенаправление» будет выставлять подкаталог /site
.
Фактически, каждый должен получить доступ к базовому URL. /site
отсутствует в URL (удалив его из всех ваших внутренних гиперссылок). Затем вы внутренне переписываете все запросы, направленные на базовый URL, в подкаталог /site
. Это полностью внутренний сервер - пользователь не знает об этом. Это не внешний «редирект», это внутренний «перезапись».
Следовательно, фактические процессы:
- Принудительно установить HTTPS для всех URL.
- Внутренне переписать все запросы для базового URL (например,
example.com/
и example.com/foo
) в подкаталог /site
(например, /site/
и /site/foo
соответственно).
Однако, существует необязательный шаг # 0, если это структура URL, которая изменяется - чтобы сохранить SEO и случайный доступ. И это для «перенаправления» прямых запросов на подкаталог /site
обратно в root. Но это должно быть реализовано only , если вы уже удалили /site
из всех ваших внутренних гиперссылок - в противном случае пользователь будет перенаправляться извне при каждом нажатии, что является "медленным" для ваших пользователей и повлияет ваш сервер. Мы также должны быть осторожны с циклами перенаправления и только перенаправлять прямые запросы от пользователя и не переписывать запросы Apache.
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [OR]
RewriteCond %{REQUEST_URI} !^(.*)
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^(.*)$ /site/$1 [L,NC,R]
Если вы только имейте example.com
и www.example.com
(как вы указали в комментариях), тогда нет необходимости во всех проверках имени хоста (ie. HTTP_HOST
) - они также дублируются, поэтому вы проверяете одно и то же здесь более одного раза.
Условие, которое проверяет %{REQUEST_URI} !^(.*)
, всегда будет не выполнено («не что-нибудь» всегда ложно) Только из-за условия «ИЛИ» правило может делать что угодно.
Последний RewriteRule
безоговорочно «перенаправляет» все в подкаталог /site
. Это откроет подкаталог /site
. Вы также можете ожидать, что это создаст бесконечное перенаправление l oop, если у вас нет другого файла .htaccess
в подкаталоге /site
, который предотвращает это.
^(.*)$
- нет необходимости захватывать URL-путь, если вы не используете обратную ссылку в подстановке RewriteRule
. В вашем перенаправлении HTTP на HTTPS это можно упростить до ^
- так как это просто необходимо для успешного выполнения каждого запроса.
Попробуйте вместо этого:
RewriteEngine On
# 1. HTTP to HTTPS redirect (same host)
RewriteCond %{SERVER_PORT} 80
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# 2. Internally rewrite all requests to the /site subdirectory
# Except for requests that are already for the /site subdirectory - prevent rewrite loop
RewriteRule !^site/ /site%{REQUEST_URI} [L]
Нет необходимости Оболочка <IfModule>
.
И, опционально, перенаправлять внешние запросы для прямого подкаталога /site
обратно на root (канонический URL). NB. Только если во всех внутренних гиперссылках подкаталог /site
был удален из URL. Это будет go перед вышеуказанными директивами.
# 0. Redirect direct /site requests back to the root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^site/(.*) https://%{HTTP_HOST}/$1 [R=301,L]
Условие, которое проверяет переменную окружения REDIRECT_STATUS
, (вероятно) требуется для предотвращения перенаправления l oop, поскольку мы не хотим перенаправлять уже переписанный запрос по правилу № 2.
Рекомендуется сначала выполнить проверку с 302 (временными) перенаправлениями, чтобы избежать потенциальных проблем с кэшированием.
Вам нужно очистить кеш браузера перед тестированием.
Также рассмотрите возможность канонизации www subdomain.
ОБНОВЛЕНИЕ № 1: Чтобы иметь возможность Получите доступ к другим файлам в документе root или файлам вне подкаталога /site
, после чего вам нужно будет добавить условие в правило № 2, чтобы исключить запросы, которые отображаются непосредственно в файлы. Например:
# 2. Internally rewrite all requests to the /site subdirectory
# Except for requests that are already for the /site subdirectory - prevent rewrite loop
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^site/ /site%{REQUEST_URI} [L]
ОБНОВЛЕНИЕ № 2: Я потерял доступ к защищенному паролем каталогу в example.com/site2
. Он перенаправляет на /site
и говорит «файл не найден».
Вы можете сделать исключение только для этого одного подкаталога. Например, отредактируйте вышеприведенное правило следующим образом:
# 2. Internally rewrite all requests to the /site subdirectory
# Except for requests that are already for the /site or /site2 subdirectories
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^(site|site2) /site%{REQUEST_URI} [L]
ИЛИ сделайте исключение для всех каталогов, кроме каталога root, который все равно необходимо переписать в /site/
, чтобы Сервер вашей домашней страницы. Например:
# 2. Internally rewrite all requests to the /site subdirectory
# Except for requests that are already for the /site subdirectory
# Or any [sub]directory...
RewriteCond %{REQUEST_URI} ^/$ [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^site /site%{REQUEST_URI} [L]