回答:
mod_rewrite
ルールはhttpd.conf
ファイル内またはファイル内に配置.htaccess
できます。にアクセスできる場合はhttpd.conf
、ここにルールを配置するとパフォーマンスが向上します(.htaccess
ファイルが呼び出されるたびにではなく、ルールが1回処理されるため)。
ロギングは、httpd.conf
ファイル(を含む<Virtual Host>
)内から有効にできます。
# logs can't be enabled from .htaccess
# loglevel > 2 is really spammy!
RewriteLog /path/to/rewrite.log
RewriteLogLevel 2
すべてのリクエストを1つのポイントに集めるには:
RewriteEngine on
# ignore existing files
RewriteCond %{REQUEST_FILENAME} !-f
# ignore existing directories
RewriteCond %{REQUEST_FILENAME} !-d
# map requests to index.php and append as a query string
RewriteRule ^(.*)$ index.php?query=$1
Apache 2.2.16以降では、も使用できますFallbackResource
。
301/302リダイレクトの処理:
RewriteEngine on
# 302 Temporary Redirect (302 is the default, but can be specified for clarity)
RewriteRule ^oldpage\.html$ /newpage.html [R=302]
# 301 Permanent Redirect
RewriteRule ^oldpage2\.html$ /newpage.html [R=301]
注:外部リダイレクトは暗黙的に302リダイレクトです。
# this rule:
RewriteRule ^somepage\.html$ http://google.com
# is equivalent to:
RewriteRule ^somepage\.html$ http://google.com [R]
# and:
RewriteRule ^somepage\.html$ http://google.com [R=302]
SSLの強制
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://example.com/$1 [R,L]
一般的なフラグ:
[R]
または[redirect]
-リダイレクトを強制します(デフォルトは302一時リダイレクト)[R=301]
または[redirect=301]
-301永久リダイレクトを強制します[L]
または[last]
-書き換えプロセスを停止します(一般的な落とし穴の下記の注を参照)[NC]
または[nocase]
-照合で大文字と小文字を区別しないことを指定します
多くの場合、長い形式のフラグを使用すると読みやすくなり、後でコードを読む人が助けになります。
複数のフラグをコンマで区切ることができます。
RewriteRule ^olddir(.*)$ /newdir$1 [L,NC]
mod_alias
スタイルリダイレクトとの混合mod_rewrite
# Bad
Redirect 302 /somepage.html http://example.com/otherpage.html
RewriteEngine on
RewriteRule ^(.*)$ index.php?query=$1
# Good (use mod_rewrite for both)
RewriteEngine on
# 302 redirect and stop processing
RewriteRule ^somepage.html$ /otherpage.html [R=302,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# handle other redirects
RewriteRule ^(.*)$ index.php?query=$1
注:あなたは混在させることができるmod_alias
とmod_rewrite
、それだけで上記のように、基本的なリダイレクトを扱うより多くの作業を必要とします。
コンテキストは構文に影響します
.htaccess
ファイル内では、RewriteRuleパターンで先頭のスラッシュは使用されません。
# given: GET /directory/file.html
# .htaccess
# result: /newdirectory/file.html
RewriteRule ^directory(.*)$ /newdirectory$1
# .htaccess
# result: no match!
RewriteRule ^/directory(.*)$ /newdirectory$1
# httpd.conf
# result: /newdirectory/file.html
RewriteRule ^/directory(.*)$ /newdirectory$1
# Putting a "?" after the slash will allow it to work in both contexts:
RewriteRule ^/?directory(.*)$ /newdirectory$1
【L】じゃあない!(時々)
[L]
フラグは、任意のさらなる書き換え規則の処理を停止し、ルール・セットを通るその通過のために。ただし、そのパスでURLが変更されていて、.htaccess
コンテキストまたは<Directory>
セクションにいる場合、変更されたリクエストはURL解析エンジンを介して再度渡されます。そして、次のパスでは、今回は別のルールに一致する可能性があります。これを理解していない場合は、[L]
フラグが効果がないように見えることがよくあります。
# processing does not stop here
RewriteRule ^dirA$ /dirB [L]
# /dirC will be the final result
RewriteRule ^dirB$ /dirC
書き換えログは、ルールが2回実行され、URLが2回更新されることを示しています。
rewrite 'dirA' -> '/dirB'
internal redirect with /dirB [INTERNAL REDIRECT]
rewrite 'dirB' -> '/dirC'
これを回避する最善の方法は、ルール(およびその後のパス)の処理をすべて停止したい場合は、フラグの代わりに[END]
フラグ(Apache docsを参照)を使用する[L]
ことです。ただし、この[END]
フラグはApache v2.3.9 +でのみ使用できるため、v2.2以下を使用している場合は、フラグのみが表示されます[L]
。
以前のバージョンでは、RewriteCond
ステートメントに依存して、以降のURL解析エンジンのパスでのルールの一致を防ぐ必要があります。
# Only process the following RewriteRule if on the first pass
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ...
または、RewriteRuleがコンテキスト(つまりhttpd.conf
)内にあり、リクエストが再解析されないようにする必要があります。
[L]
フラグはルールがあることを意味し、最後彼らは内部リダイレクトされているので、あなたはので、これは、書き換え停止しません、現在処理中dirB
に適用されるdirC
次のhtaccessの処理に。単独でRewriteRule ^(.*)$ index.php?query=$1
は、内部リダイレクトの無限ループになります(実際には、10回の反復で終了します)。-1は、[L]が最後ではないことを示唆しているためです。書き換えプロセスを終了するわけではありませんが、最後です。
RewriteCond %{HTTPS} off
(HTTPSへの非SSLトラフィックを強制的にあなたの例で)HTTPS接続をチェックするための望ましい方法です
.*
と[L]
私はここに来た前に私が読んフラグ。
200
、!=200
、^.
、^$
。どうやら、変数は200
リダイレクト用に設定されますが、他のページ(エラーなど)もそれを何らかの値に設定します。これis empty
はis not empty
、is 200
必要is not 200
に応じて、、、またはのいずれかを確認することを意味します。
RewriteBaseとの取引:
ほとんどの場合、RewriteBaseを設定する必要があります。そうでない場合、Apacheはベースがディレクトリへの物理ディスクパスであると推測します。だからこれから始めましょう:
RewriteBase /
RewriteBase .
、または指定したものを変更するだけでURLを同じに保つ必要があることを示すものはありますか?
RewriteBase
で相対パス置換を使用している場合にのみ設定する必要がありますRewriteRule
。相対パスを使用しないことをお勧めします。
RewriteBase
開発チームでは、ほぼすべての開発者がそれが何をしているのか誤解しているので、私たちは完全に回避しています。@ w3dが言ったように、文字を保存し、同じベースを1つのファイル内のすべてのRewriteRulesに適用する場合にのみ必要です。あなたがそれを避ければあなたのコードはおそらく他の人にとってより明確になるでしょう。
その他の落とし穴:
1-時には、マルチビューを無効にすることをお勧めします
Options -MultiViews
私はすべてのMultiViews機能に精通していませんが、アクティブなときにmod_rewriteルールを台無しにすることを知っています。 。
説明します。Webディレクトリに2つのphpファイル、file1.phpとfile2.phpがあり、これらの条件とルールを.htaccessに追加するとします。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ file1.php/$1
ファイルまたはディレクトリに一致しないすべてのURLがfile1.phpによって取得されると想定します。驚き!このルールは、URL http:// myhost / file2 / somepathには適用されません。。代わりに、file2.phpの内部に移動します。
何が起こっているのかというと、MultiViewsは実際に必要なURLがhttp://myhost/file2.php/somepathであると自動的に推測したということです。と喜んでそこに連れて行ってくれました。
さて、あなたは何が起こったのか手がかりがなく、その時点でmod_rewriteについて知っていると思ったすべてのものに疑問を投げかけています。次に、ルールをいじって、この新しい状況の背後にあるロジックを理解しようとしますが、テストするほど、意味がわかりにくくなります。
つまり、mod_rewriteを論理に近い方法で機能させたい場合、MultiViewをオフにすることは正しい方向への一歩です。
2- FollowSymlinksを有効にする
Options +FollowSymLinks
その1つ、私は本当に詳細はわかりませんが、何度も言及されているのを見てきました。
+FollowSymLinks
mod_rewrite
あいまいなセキュリティ上の理由から、ドキュメントでは、がまったく機能することが必須であると記載されています。
方程式は次の例で行うことができます:
RewriteCond %{REQUEST_URI} ^/(server0|server1).*$ [NC]
# %1 is the string that was found above
# %1<>%{HTTP_COOKIE} concatenates first macht with mod_rewrite variable -> "test0<>foo=bar;"
#RewriteCond search for a (.*) in the second part -> \1 is a reference to (.*)
# <> is used as an string separator/indicator, can be replaced by any other character
RewriteCond %1<>%{HTTP_COOKIE} !^(.*)<>.*stickysession=\1.*$ [NC]
RewriteRule ^(.*)$ https://notmatch.domain.com/ [R=301,L]
動的負荷分散:
mod_proxyを使用してシステムのバランスをとる場合、ワーカーサーバーのダイナミックレンジを追加することが可能です。
RewriteCond %{HTTP_COOKIE} ^.*stickysession=route\.server([0-9]{1,2}).*$ [NC]
RewriteRule (.*) https://worker%1.internal.com/$1 [P,L]
[L]フラグの理解を深めることが適切です。[L]フラグは最後です。URL解析エンジンを介してリクエストが再度ルーティングされる原因を理解する必要があります。ドキュメントから(http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_l)(鉱山を強調):
[L]フラグにより、mod_rewriteはルールセットの処理を停止します。ほとんどのコンテキストでは、これは、ルールが一致した場合、それ以上のルールは処理されないことを意味します。これは、Perlの最後のコマンド、またはCのbreakコマンドに対応します。このフラグを使用して、現在のルールをさらにルールを考慮せずにすぐに適用する必要があることを示します。
.htaccessファイルまたは
<Directory>
セクションで RewriteRuleを使用している場合は、ルールの処理方法をある程度理解しておくことが重要です。この単純化された形式は、ルールが処理されると、書き換えられた要求が URL解析エンジンに戻され、それを使用して何が行われるかを示します。書き換えられた要求が処理されると、.htaccessファイルまたは<Directory>
セクションが再び検出される可能性があり、そのため、ルールセットが最初から再度実行される可能性があります。最も一般的には、これは、ルールの1つがリダイレクト(内部または外部)を引き起こし、要求プロセスが最初からやり直した場合に発生します。
したがって、[L]フラグは、ルールセットを通過するそのための以降の書き換えルールの処理を停止します。ただし、[L]のマークが付いたルールがリクエストを変更し、.htaccessコンテキストまたは<Directory>
セクションにいる場合、変更されたリクエストはURL解析エンジンを介して再度渡されます。そして、次のパスでは、今回は別のルールに一致する可能性があります。何が起こったのか理解できない場合、[L]フラグを使用した最初の書き換えルールは効果がないようです。
これを回避する最善の方法は、本当に停止したい場合は、[L]フラグの代わりに[END]フラグ(http://httpd.apache.org/docs/current/rewrite/flags.html#flag_end)を使用することです。ルールの以降のすべての処理(およびその後の再解析)。ただし、[END]フラグはApache v2.3.9 +でのみ使用できるため、v2.2以下を使用している場合は、[L]フラグのみが表示されます。この場合、RewriteCondステートメントに依存して、URL解析エンジンの後続のパスでのルールの一致を防ぐ必要があります。または、RewriteRuleがコンテキスト(つまりhttpd.conf)内にあり、リクエストが再解析されないようにする必要があります。
もう1つの優れた機能は、rewrite-map-expansionsです。あなたがホストの膨大な量/処理のための書き換えを持っている場合、それらは特に便利です:
これらは、Key-Value-Replacementのようなものです。
RewriteMap examplemap txt:/path/to/file/map.txt
次に、次のようなルールでマッピングを使用できます。
RewriteRule ^/ex/(.*) ${examplemap:$1}
このトピックの詳細については、こちらをご覧ください。
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#mapfunc
.htaccess
ベースの書き換えを使用している場合は、この機能を無視してください。このコンテキストでは機能しません。
mod_rewriteは、環境変数の設定、Cookieの設定など、URLを変更せずにリクエスト処理の側面を変更できます。これは非常に便利です。
環境変数を条件付きで設定します。
RewriteCond %{HTTP_COOKIE} myCookie=(a|b) [NC]
RewriteRule .* - [E=MY_ENV_VAR:%b]
503応答を返します:
RewriteRule
の[R]
フラグは3xx以外の値を取り、リダイレクトされない応答を返すことができます。たとえば、管理されたダウンタイム/メンテナンスの場合:
RewriteRule .* - [R=503,L]
503レスポンスを返します(リダイレクト自体ではありません)。
また、mod_rewriteはmod_proxyへの強力なインターフェースのように機能できるため、ProxyPass
ディレクティブを記述する代わりにこれを行うことができます。
RewriteRule ^/(.*)$ balancer://cluster%{REQUEST_URI} [P,QSA,L]
意見:RewriteRule
sとRewriteCond
sを、リクエストの事実上考えられるあらゆる側面に基づいてリクエストを異なるアプリケーションまたはロードバランサーにルーティングすることは、非常に強力です。バックエンドに向かう途中で要求を制御し、戻るときに応答を変更できるため、mod_rewriteはルーティング関連のすべての構成を集中管理するのに理想的な場所になります。
時間をかけて習得してください。それだけの価値があります。:)