Назад | Перейти на главную страницу

Объединение более 1 перезаписи Apache: перенаправление домена виртуального хоста и перенаправление входного файла

Я застрял на использовании условий 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] флаг.

Я прав? Может кто-нибудь подтвердить или опровергнуть это объяснение? А может уточнить?