明確にするために、これは this one のような重複した質問ではありません。質問のコアが異なるためです。私がやろうとしているのは、言語コード(通常はen
またはcz
)を使用してサイトにアクセスしようとするユーザーを、言語変数が設定されたindex.php
にリダイレクトすることです。サイト自体は英語とチェコ語の設定のみを認識でき、他のすべては訪問者のIPジオロケーションに基づいてリダイレクトされます(外部のオンラインJSON APIを使用)。しかし、問題は、ブラウザがリダイレクトを繰り返し続け、リダイレクトが多すぎるというエラーを返すことです。どうしましたか?エラーを探しようとしましたが、何も表示されませんでした。
これは完全な.htaccess
ファイルです:
Options -Indexes
RewriteEngine on
RewriteRule ^[a-z]{2,3}/$ /index.php?lang=$1
RewriteRule ^blog/?(.*)$ //blog.czghost.czlh/$1 [R=301]
RewriteRule ^ftp/?(.*)$ //ftp.czghost.czlh/$1 [R=301]
また、ユーザーがindex.php?lang=$1
で書き込んだ場合、代わりにユーザーをニースURLバリアントにリダイレクトする必要があります。オンラインで検索しましたが、複雑すぎるようです:(
オンラインで展開する準備ができる前に、Windowsマシン上のWAMPサーバーでサイトをテストしています。
リダイレクトループをトリガーするリクエストしているURLを実際に述べていませんか?
ただし、投稿したディレクティブから、/blog<anything>
または/ftp<anything>
の形式のリクエストはリダイレクトループを引き起こすように思われます。
RewriteRule ^blog/?(.*)$ //blog.czghost.czlh/$1 [R=301] RewriteRule ^ftp/?(.*)$ //ftp.czghost.czlh/$1 [R=301]
Apache mod_rewriteは、RewriteRule
substitutionのプロトコル相対URLをサポートしていません-それらは単にルート相対(つまり、ドキュメントルートに相対的なURLパス)と見なされます。おそらく、このリダイレクトループの結果がブラウザのアドレスバーに表示されますか?それは次のようになります:
http://example.com/blog/xyz
http://example.com//blog.czghost.czlh/xyz
にリダイレクトしますhttp://example.com//blog.czghost.czlh/.czghost.czlh/xyz
にリダイレクトしますhttp://example.com//blog.czghost.czlh/.czghost.czlh/.czghost.czlh/xyz
にリダイレクトしますプロトコルを含める必要があります。例えば:
RewriteRule ^blog/?(.*)$ https://blog.czghost.czlh/$1 [R=301,L]
リダイレクトをすぐにトリガーし、さらに書き換えられるリスクを冒さないようにするため、L
(last
)フラグも含めました。これは、実際には内部書き換え(index.php
に書き換える)の前に行う必要があります。
誤った301(permanent)リダイレクトがブラウザによってキャッシュされるため、ブラウザのキャッシュをクリアしたことを確認する必要があります。このため、302(一時)リダイレクトを使用するとテストが簡単になる場合があります。
blog
およびftp
ルールは、alternationを使用して、単一のディレクティブで処理できます。例えば:
RewriteRule ^(blog|ftp)/?(.*)$ https://$1.czghost.czlh/$2 [R=301,L]
RewriteRule ^[a-z]{2,3}/$ /index.php?lang=$1
RewriteRule
patternにキャプチャグループ(つまり、括弧で囲まれたサブパターン)がないため、$1
後方参照は常に空になります。これは次のように書き直す必要があります。
RewriteRule ^([a-z]{2,3})/$ /index.php?lang=$1 [L]
繰り返しになりますが、それ以上の書き換えを防ぐために、L
フラグを含めました。これは、URLパスの末尾にスラッシュサフィックスがあることを想定していることに注意してください。したがって、/blog/en/
(スラッシュサフィックス付き)の形式のURLのみが正常に書き換えられます(ただし、これは無関係かもしれません)。
したがって、要約すると、これは次のように書き直す必要があります。
RewriteRule ^(blog|ftp)/?(.*)$ https://$1.czghost.czlh/$2 [R=301,L]
RewriteRule ^([a-z]{2,3})/$ /index.php?lang=$1 [L]
また、ユーザーが
index.php?lang=$1
で書き込んだ場合、代わりにユーザーをニースURLバリアントにリダイレクトする必要があります。
追加のリダイレクトでこれを行うことができますbefore上記のディレクティブ。例えば:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^lang=([a-z]{2,3})$
RewriteRule ^(index\.php)?$ /%1/? [R=301,L]
クエリ文字列をQUERY_STRING
サーバー変数と照合するには、RewriteCond
ディレクティブを使用する必要があります(これは、RewriteRule
ディレクティブでは実行できません)。 REDIRECT_STATUS
環境変数に対する前述のチェックは、URLを/index.php?lang=xyz
に書き換える後のディレクティブによって、最初のリクエストのみを処理し、書き換えられたリクエストを処理しないことを確認することです。 REDIRECT_STATUS
env varは最初のリクエストでは空ですが、最初に成功した後(200 OK-HTTPステータスのように)「200」に設定されます書き換え。
これは、index.php
または空のURLパス(例:/?lang=xyz
)のいずれかに一致します。 %1
は最後に一致したCondPatternへの後方参照です(RewriteRule
patternへの後方参照である$N
とは対照的です) 。リダイレクトされたURLからクエリ文字列を削除するには、RewriteRule
substitutionの末尾にある?
が必要です(または、QSD
を使用できます) Apache 2.4以降のフラグ)。
繰り返しになりますが、ブラウザによってキャッシュされない302(一時的な)リダイレクトを使用して最初にテストするのが最善です。
(コメントから:)正しく機能するのは、
/ftp/
リダイレクトだけです。/blog/
リダイレクトは空白のページに変更されていないURLのままです
同じ名前の物理ディレクトリがファイルシステムにないことを確認する必要があります。 /blog
。また、このサブディレクトリには、これを上書きする可能性のある追加の.htaccess
ファイルがありません。また、同じベース名blog
を共有するfileがないことを確認してください。例えば。 blog.html
またはblog.php
など。ある場合は、MultiViews(mod_negotiationの一部)が有効になっていないことを確認する必要があります。すなわち。 Options -Indexes -MultiViews
。 MultiViewsが有効になっている場合、Apacheはmod_rewriteがURLを書き換える前に、(たとえば)/blog.php
の内部サブリクエストを作成します。
Options -Indexes -MultiViews
RewriteEngine on
# Redirect direct requests for "index.php?lang=xyz" to "/xyz/"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^lang=([a-z]{2,3})$
RewriteRule ^(index\.php)?$ /%1/? [R=301,L]
# Redirect "blog" or "ftp/<anything>" to subdomain
RewriteRule ^(blog|ftp)/?(.*)$ https://$1.czghost.czlh/$2 [R=301,L]
# Internally rewrite "/xyz/" to "/index.php?lang=xyz"
RewriteRule ^([a-z]{2,3})/$ /index.php?lang=$1 [L]