サーバー上には、page.html
というファイル(ファイルシステム上)があり、site.com/page
としてアクセスしたいので、誰かがsite.com/page.html
にアクセスした場合、301
になります。 site.com/page
にリダイレクトします
内部で/page
-> /page.html
の書き換えを処理する書き換えルールを見てきましたが、それを301
リダイレクト/page.html
-> /page
に強制すると、私のためにループをリダイレクトします。
END
フラグは、希望どおりに実行できるように見えますが、まだサポートされていません。
また、次のようにENV
を使用してみました:
RewriteRule ^page$ /page.html [L,E=END:1]
RewriteCond %{ENV:END} !1
RewriteRule ^page.html$ /page [R=301,L]
しかし、それはリダイレクトループにもなります。
私はこれを尋ねました StackOverflowの同じ質問 。適切に機能させるには、環境変数を使用する必要があります。
RewriteRule ^page$ /page.html [L,E=LOOP:1]
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^page.html$ /page [R=301,L]
これは、mod_rewriteがルールを複数回通過するためです。最初のパスで、環境変数を設定します。 2番目のパスでは、変数にREDIRECT_
プレフィックスが付加されるため、REDIRECT_LOOP
として読み取る必要があります。
問題は、.htaccessファイルまたは<Directory>セクションでmod_rewriteを使用すると、RewriteRuleが成功するたびに(内部のものも含めて) リクエストが内部的に再起動される であり、したがって全体が書き換えられることです。再処理されるルールセット。
したがって、ユーザーが/page
にアクセスすると、内部のRewriteRuleが一致し、URLを/page.html
に書き換えます。しかし、これにより、Apacheは要求処理を再開し、ルールセットを再度実行し、external書き換えルールが一致し、/page
への301リダイレクトをトリガーします。
迅速で汚れた(しかし効果的)修正は、内部書き換えルールがredirect=no
のようなダミーパラメータをURLに追加し、外部書き換えルールでそのパラメータをチェックすることです。 スタックオーバーフローに関する同様の質問のために書いたこの回答 に基づいた例を次に示します。
RewriteEngine On
RewriteBase /
# Externally rewrite page.html -> page, unless query includes redirect=no:
RewriteCond %{QUERY_STRING} !(^|&)redirect=no(&|$)
RewriteRule ^(page)\.html$ /$1 [NS,R=301,L]
# Internally rewrite page -> page.html, add redirect=no to query:
RewriteRule ^(page)$ $1.html?redirect=no [NS,QSA]
(もちろん、使用している実際のURLパラメーターと競合する場合は、redirect=no
を他のものに置き換えてください。)
リダイレクトループを防ぐ一般的な方法は、書き換えられたURL(RewriteRule
patternが一致するURLパスではなく、初期リクエストヘッダーを含むTHE_REQUEST
サーバー変数に対してチェックすることです。に対して)、URLが書き換えられると自然に更新されます。
THE_REQUEST
の値は、URLが内部的に書き換えられるであるため変更されず、次の形式の文字列が含まれます。
GET /page.html HTTP/1.1
したがって、これは次のように書き換えられます。
# Redirect direct requests for /page.html to the canonical URL
RewriteCond %{THE_REQUEST} \.html
RewriteRule ^(page)\.html$ /$1 [R=301,L]
# Rewrite the "pretty" URL to the actual filesystem path
RewriteRule ^(page)$ $1.html [L]
この場合、THE_REQUEST
条件は、最初に要求されたURLに.html
が存在することを確認するだけです。 page.html
のチェックはRewriteRule
パターンに任されます-これはより効率的です(これは最初にチェックされるため)。
外部リダイレクトbefore内部書き換えが常に望ましいです。