Я застрял на использовании условий Apache RewriteCond и RewriteRule. Обычно я не использую их часто, и в основном документация предоставляет мне достаточно информации, чтобы самостоятельно найти решение. Однако на этот раз я застрял на том, как объединить более одной ситуации перезаписи.
В Apache 2.4.17 у меня есть виртуальный хост с серверами ServerAliases, указывающими на одно и то же имя сервера и каталог. Каждый настроенный ServerAlias должен перенаправлять на домен ServerName. Поэтому, когда я посещаю sub1.domain.com, sub2.domain.com или sub3.domain.com, все это должно быть перенаправлено по HTTP 301 на www.domain.com.
Также я хочу перенаправить все URL-адреса в один и тот же входной файл PHP. Например: www.domain.com/news/1 следует внутренне перенаправить в файл index.php в корневом каталоге виртуального хоста без изменения URL-адреса в веб-браузере пользователя.
Вышеупомянутые ситуации работают сами по себе, но когда я пытаюсь объединить ситуации в файле .htaccess, все идет не так.
Пример перенаправления моего домена:
AcceptPathInfo On
Options +MultiViews
Options +FollowSymLinks
RewriteEngine On
# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301]
Это очень хорошо работает.
И это код, который я обычно использую для внутреннего перенаправления всех URL-адресов на index.php в корневом каталоге документов, чтобы иметь возможность генерировать динамический контент на основе URL-адреса:
AcceptPathInfo On
Options +MultiViews
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.php
Это тоже очень хорошо работает. Запрос не пересылается в браузерах пользователей на index.php, а только внутренний.
Когда я пытаюсь объединить оба перенаправления:
AcceptPathInfo On
Options +MultiViews
Options +FollowSymLinks
RewriteEngine On
# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301]
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.php
Тогда все идет не так. Все запросы на других доменах (например, sub1.domain.com, sub2.domain.com/test и т. Д.) Приводят к ошибке Apache:
переехал навсегда
Документ был перемещен сюда.
Кроме того, при попытке использовать ErrorDocument для обработки запроса возникла ошибка 301 Moved Permanently.
Хотя www.domain.com/test правильно обслуживает содержимое index.php в корне документа.
Когда я пытаюсь изменить порядок условий и правил:
AcceptPathInfo On
Options +MultiViews
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.php
# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301]
Затем sub1.domain.com был правильно перенаправлен в браузере пользователя на www.domain.com, но когда я добавляю к нему URI, например sub1.domain.com/test, он перенаправляется на www.domain.com/index.php вместо www.domain.com/test и извлекает только содержимое index.php из корневого каталога документов.
Запрос www.domain.com/test напрямую в этом случае работает хорошо: содержимое index.php в корне документа отображается вместо перенаправления пользователя на index.php.
Я считаю, что он должен что-то делать с некоторыми флагами, но не знаю, как их применить. Кто мне объяснит, на что я должен обращать внимание?
Я думаю, что уже решил проблему, добавив [L]
флаг как RewriteRule
линий.
Это мой файл htaccess прямо сейчас:
AcceptPathInfo On
Options +MultiViews
Options +FollowSymLinks
RewriteEngine On
# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301,L]
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.php [L]
Насколько я понимаю, Apache сначала рассмотрит
RewriteCond %{HTTP_HOST} !^www.domain.com$
а затем выполнить
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301,L]
С тех пор RewriteRule
имеет [L]
набор флагов Apache не будет проверять наличие других правил.
Когда полный URL не соответствует первому RewriteCond
Apache пропустит это RewriteCond
/ RewriteRule
комбинировать и идти по делу с
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^.*$ ./index.php [L]
Которые только внутренние перенаправления. И теперь это не сочетается с первым RewriteRule
потому что RewriteRule
пропускается из-за этого [L]
флаг.
Я прав? Может кто-нибудь подтвердить или опровергнуть это объяснение? А может уточнить?