Apache vhostsファイルに同じルールを使用できるという信念の下で、以前に正常に実装したいくつかの.htaccess
ルールを組み合わせて、ワイルドカードサブドメインRewriteRule
を設定しようとしています。
本質的に、example.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以外のサブドメインの試行では、期待どおりに機能し、標準のexample.com
でも問題なく機能します。
<VirtualHost *:80>
ServerAdmin [email protected]
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 [email protected]
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]
私は(一見)2番目の仮想ホストエントリの代わりに以下を使用することである程度の成功を収めました。サブドメインを使用すると、process.php
ページが出力されます。パターンマッチングはその点で機能しているように見えますが、実際のprocess.php
は、予期されるサブドメインを文字列としてではなく、空の変数を受け取ります(process.php?p=%2
の場合)。
<VirtualHost *:80>
ServerAdmin [email protected]
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>
私はこれを回りくどい方法で解決しましたが、それが最もエレガントな方法であるかどうかはわかりません。
上記のpdate 1コードを使用すると、クエリ文字列がまだ追加されているのに、%2
ページのGET
がprocess.php
を受信していないことがわかりました。私のコードの指示に従って、URLがブラウザへのURLにp=abc
変数を表示しないにもかかわらず、内部URLがそれらを渡したと誤って想定した可能性があります。それでも、process.php
はPHP
の$_SERVER['HTTP_X_FORWARDED_Host']
を使用してサブドメインを文字列として判別し、最初のアイデアと同じようにページ上の変数として使用できることに気付きました。
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
パターン)の2番目にキャプチャされたグループへの後方参照であるためです。最後に一致したCondPatternは^/$
であり、キャプチャされたグループがないため、%2
は常に空です。
その3番目のRewriteCond
ディレクティブは、とにかく不要に見えます。これはすでにRewriteRule
パターン^$
によってチェックされています(ディレクトリごとのコンテキストでは、ディレクトリプレフィックスが削除されているため、これは正しいです)。
最初のRewriteCond
ディレクティブも不要に見えます。 www.example.com
のリクエストは、最初のVirtualHostによってキャッチされるため、このVirtualHost内のhostnameはwww.example.com
になることはなく、このディレクティブは常にtrueと評価されます。
私はこれを次のように書き直します:
RewriteCond %{HTTP_Host} ^(?:www\.)?([^.]+)\.example\.com$ [NC]
RewriteRule ^$ process.php?p=%1 [QSA]
私は最初のgroup非キャプチャーを作成しました。 (?:www\.)
-?:
は、キャプチャしないようにします。したがって、実際のサブドメインに対してのみ%1
を取得します。また、文字クラスでドットをエスケープする必要はありません(リテラルドットと一致させるため)。ここでは、NC
のRewriteRule
フラグは不要です。
RewriteRule
ディレクティブでURLパスを指定したため、RewriteBase
substitutionのスラッシュプレフィックスも削除しました。
これは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ファイルの場合と同じように変更されません。