Я пытаюсь установить поддомен с подстановочными знаками RewriteRule
, объединив некоторые правила .htaccess
, которые я успешно реализовал ранее, полагая, что я могу использовать те же правила для моего файла vhosts Apache.
По сути, пример. com
и www.example.com
перейдите по корневому пути и найдите index.php
. Все остальные (динамические) запросы субдоменов на корневом уровне, такие как abc.example.com
, перезаписываются (невидимы для браузера) на example.com/process.php?p=abc
.
Во-вторых, любые запросы файлов из субдомена за пределами базового / корневого уровня должны быть переписаны, чтобы их можно было получить из корневого пути стандартного домена без субдомена. Итак, abc.example.com/css/style.css
должен происходить с example.com/css/style.css
Это моя попытка сделать это. Я получаю сообщение об ошибке Apache:
У вас нет разрешения на доступ к /index.php на этом сервере.
для любой попытки поддомена, кроме www, который работает должным образом, а также стандартного пример. com
, который по-прежнему работает нормально.
<VirtualHost *:80>
ServerAdmin webmaster@example.com
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public_html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@example.com
ServerName other.example.com
ServerAlias *.example.com
DocumentRoot /var/www/example.com/public_html/
<Directory /var/www/example.com/public_html/>
Options FollowSymLinks
AllowOverride all
Require all granted
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
RewriteRule ^$ /process.php?p=%2 [QSA,NC]
RewriteCond %{REQUEST_FILENAME} !^$ [NC]
RewriteRule ^(.*) http://www.example.com/$1 [P]
</Directory>
</VirtualHost>
Я основал это на успешном перенаправлении корневого каталога другого домена на example.com
с помощью этого файла .htaccess
, который включает process.php
и отправляет все остальные запросы в корень example.com
.
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# Check the request isn't an existing file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^$ http://www.example.com/process.php [P]
RewriteCond %{REQUEST_FILENAME} !^$ [NC]
RewriteRule ^(.*) http://www.example.com/$1 [P]
А также отключив этот тест .htaccess
, я побежал перенаправить субдомен в качестве переменной для process.php
успешно, хотя он не перехватил другие файловые запросы, такие как пример css выше:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
RewriteRule ^$ /process.php?p=%2 [QSA,NC]
У меня (по-видимому) некоторый успех с используя следующее вместо моей второй записи виртуального хоста. Страница process.php
выводится, если я использую поддомен. Хотя сопоставление с образцом, кажется, работает в этом отношении, мой реальный процесс . php
получает пустую переменную, а не ожидаемый субдомен в виде строки (для: process.php? p =% 2
):
<VirtualHost *:80>
ServerAdmin webmaster@example.com
ServerName other.example.com
ServerAlias *.example.com
DocumentRoot /var/www/example.com/public_html
<Directory /var/www/example.com/public_html>
Options FollowSymLinks
AllowOverride all
Require all granted
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?([^\.]+)\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^$ /process.php?p=%2 [NC,QSA]
</Directory>
</VirtualHost>
Я решил это в окольный путь, но я не уверен, что это самый элегантный способ.
Используя приведенный выше код update 1 , я увидел, что любая строка запроса все еще добавляется, но % 2
не получал GET
на моей странице process.php
. Возможно, я ошибочно предположил, что, хотя URL-адрес не отображает переменную p = abc
в URL-адресе для браузера, в соответствии с инструкциями моего кода, внутренний URL-адрес все еще передает их. Тем не менее, я понял, что process.php
все еще может определять субдомен как строку, используя $ _ SERVER [' HTTP_X_FORWARDED_HOST ']
в PHP
и использовать его в качестве переменной на странице аналогично моей первоначальной идее.
RewriteCond% {HTTP_HOST}! ^ Www \ .example \ .com $ [NC] RewriteCond% {HTTP_HOST} ^ (www \.)? ([^ \.] +) \. Example \ .com $ [NC] RewriteCond% {REQUEST_URI} ^ / $ RewriteRule ^ $ /process.php?p=%2 [NC, QSA]
Обратная ссылка % 2
не была установлена, потому что это обратная ссылка на вторую захваченную группу из последнего сопоставленного CondPattern ( RewriteCond
шаблона). Последний совпавший CondPattern - это ^ / $
, у которого нет захваченных групп, поэтому % 2
всегда пусто.
Эта 3-я директива RewriteCond
выглядит в любом случае лишнее. Это уже проверяется шаблоном RewriteRule
^ $
(в контексте каталога каталог-префикс удален - значит, это правильно).
Первая директива RewriteCond
тоже выглядит лишней. Любой запрос для www.example.com
будет перехвачен первым VirtualHost, поэтому имя хоста внутри этого VirtualHost никогда не будет www.example.com
в любом случае, поэтому эта директива всегда имеет значение true.
Я бы переписал это как:
RewriteCond %{HTTP_HOST} ^(?:www\.)?([^.]+)\.example\.com$ [NC]
RewriteRule ^$ process.php?p=%1 [QSA]
Я сделал первую группу не захватывающей, т.е. (?: www \.)
- ?:
делает его не захватывающим. Таким образом, мы всегда получаем % 1
для фактического поддомена. Кроме того, нет необходимости экранировать точку (чтобы соответствовать буквальной точке) в классе символов. Флаг NC
в RewriteRule
здесь лишний.
Я также удалил префикс косой черты в подстановке RewriteRule
, поскольку вы указали URL-путь в директиве RewriteBase
.
Это только перезаписывает abc.example.com/
, т.е. запрос на корень документа.
Во-вторых, любые запросы файлов из субдомена за пределами базового / корневого уровня должны быть переписаны, чтобы они были получены из корневого пути стандартного домена без субдомена. Итак,
abc.example.com/css/style.css
должен происходить сexample.com/css/style.css
.
Начиная с abc.example.com /
и example.com/
указывают на то же место в файловой системе, которое я не вижу, поскольку вам здесь нужно что-то делать? example.com/css/style.css
должен указывать на тот же файл, что и abc.example.com/css/style.css
.
А как насчет других файлов в документе? корень? например. abc.example.com/file
. На данный момент это просто проходит без изменений, что и для файлов CSS.