web-dev-qa-db-ja.com

リダイレクトループを発生させずに書き換えを使用してURLから拡張子を削除する

サーバー上には、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]

しかし、それはリダイレクトループにもなります。

4
arcyqwerty

私はこれを尋ねました 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として読み取る必要があります。

3

問題は、.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を他のものに置き換えてください。)

3
Ilmari Karonen

リダイレクトループを防ぐ一般的な方法は、書き換えられたURL(RewriteRulepatternが一致する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内部書き換えが常に望ましいです。

0
MrWhite