.htaccess  RewriteCond, RewriteRule, 各種一覧表

ルーティングに使うmod_rewrite記述方法。 記述方法が非常にややこしく忘れやすいので、ここにまとめて載せてます。 気が付いた時に追記していきます。 間違いや追記したらいい内容はコメントから教えて戴けると嬉しいです。

.htaccess 適用範囲

.htaccessファイルに記述内容は、その.htaccessファイルのディレクトリを含んだ、子のディレクトリに適用される。

子ディレクトリに.htaccessがある場合は下位のディレクトリの内容が優先される。 子ディレクトリの.htaccessに設定が無い場合、親ディレクトリの.htaccessの内容が継承される。

.htaccess 書き方

こんな感じで、EngineをOnして、.htaccessがあるディレクトリをRewriteBaseで基準ディレクトリに設定して、

<IfModule mod_rewrite.c>
    #この間にディレクティブを書いていく
    RewriteEngine On
    RewriteBase /
    RewriteCond %{HTTP_HOST} !^localhost(?::\d+)?$ [NC]
    RewriteCond %{REQUEST_URI}  (/test/socket.io)  [NC]
    RewriteRule ^(.*)$ http://localhost:60000/$1 [L,P]
</IfModlue>

Moduleにmod_rewrite.cがあれば、~内を実行。

(?::\d+)?は、()があってもなくても、”::”に続いて数字”\d”が1桁以上ある”+”場合にマッチする。要はポート番号が付いていたらと言う意味。

上の例は、socket.ioのリクエストが来たら、socket.ioサーバーがListenしているポート60000にルーティングしています。

コメント

行の先頭に#を付ける。

ディレクティブ一覧

RewriteRuleで渡されるURLは、サーバーの.htaccessでは”/”から始まるが、各子ディレクトリの.htaccessでは先頭には”/”が付かないので注意。

ディレクティブ説明
RewriteEngine 
ディレクティブ
Rewrite Engineの使用を指定
RewriteEngineディレクティブはURLの書き換えをおこなう。(初期値Off)
RewriteEngine On

コメントアウトするより部分的に動作をOFFにする時にも使用。
RewriteBase 
ディレクティブ
RewriteBase は「Rewrite機能」の基準となるディレクトリを指定する。
◆.htaccessが存在する下の基準ディレクトリ
RewriteBase /

RewriteBase
RewriteCond
 ディレクティブ
URLを書き換える条件文。
RewriteRule
 ディレクティブ
実行命令文、正規表現パターンにマッチしたら、全体を置換URLに置き換える。
RewriteRule 正規表現パターン 置換URL [フラグ]

連続して記述して、それがつながる記述になっていると連続してリダイレクトされる。
以下は、Requestはindex_Aだがindex_Bにリダイレクトされ、更にindex_Cにリダイレクトされる。
RewriteRule ^index_A\.html$ /blog/index_B.html [R=301]
RewriteRule ^index_B\.html$ /blog/index_C.html [R=301]
これを回避する為、Lフラグを付ける
Redirect permanent / https://example.jp/サイト全体を転送
RewriteOptions
ディレクティブ
特殊オプションをセットする
inherit:上位ディレクトリの設定を下位ディレクトリに継承。
AllowAnyURI:(非推奨)どんな URI も書き換えることが可能。
MergeBase:RewriteBaseの設定が下位ディレクトリにも継承。

フラグ一覧

ディレクティブに使用。

フラグ説明
R (Redirect)R:リダイレクト:別のページに転送。(コード省略時は302)

R=301:最も一般的なWebページ転送。WebページのSEO評価も引き継ぎ永続的に転送。 Google対応早い。
R=302:評価も引き継がれるが、一時的な転送でGoogleの対応遅い。
R=404:強制的に404エラーを返す

*リライトは転送はするがブラウザのURLは元のまま。 リダイレクトは改めてリクエストが送信されるので、ブラウザのURLも変更される。
L (Last)Lフラグがあるとマッチするとそれ以降のruleは実行しないが、.htaccessでは動作しない。
以下は、Requestはindex_Aだがindex_Bにリダイレクトされ、更にindex_Cにリダイレクトされる。
RewriteRule ^index_A\.html$ /blog/index_B.html [R=301, L]
RewriteRule ^index_B\.html$ /blog/index_C.html [R=301, L]
P (Proxy)プロキシで、別オリジンからデータを取得して返却するリバースプロキシとして動作させることが出来る。

mod_proxyが組み込まれている必要がある。
NC (No Case)正規表現パターン評価時、大文字と小文字を区別しない。
NE (No Escape)特殊文字が16進数のコードエスケープされないようにする。例えば、リライトやリダイレクト時NEフラグがなければ、アンカーの#topic1は%23topic1となりエラーとなる。

RewriteRule 正規表現パターン 置換URL [R=301, NE]
ORRewriteCondを縦に連続して記述するとANDとなり、一つでも偽になったら最後のRewriteCondの直後のRewriteRuleは実行されない。[OR]フラグでOR設定ができる。

以下の3つの何れかが新なら次に進める。
RewriteCond xxx1 xxxxx1 [OR]
RewriteCond xxx2 xxxxx2 [OR]
RewriteCond xxx3 xxxxx3
C (Chain)
F (Forbidden:閲覧禁止)Fフラグがあるとクライアントに403 Forbiddenエラーを返す。

RewriteRule 正規表現パターン - [F]
G (Gone:消滅)Gフラグがあるとクライアントに410 Goneエラーを返す。

RewriteRule 正規表現パターン - [G]
QSA (Query String Append)以前のクエリも新しいクエリを付加する場合 (QSAフラグ)
RewriteRule ^old/hello.html$ /new/hello.html?user_id=100 [R=301, QSA]
E (Environment)環境変数の値を設定・削除できる。
設定する場合は、 [E=変数名:値]、
値を削除する場合は [E=!変数名]
RewriteRule 正規表現パターン 置換URL [E=環境変数名]
B書き換え処理の前に英数字以外の文字をエスケープ(パーセントエンコーディング)する。
CO (Cookie)Cookie を設定。
[CO=クッキー名:値]
DPI (Discard Path)URI の PATH_INFO を破棄する。
H (Handler)実行するアプリケーションのハンドラを強制的に指定する。
N (Next)書き換え処理を先頭から再実行する。
その際、検証するURLは最後にRewriteRuleで書き換えられたURL。
無限ループになる可能性あり。
NS (No Subreq)サーバ内部で発生するサブリクエストには、書き換え処理を行わない。
PT (Pass Through)RewriteRule の置換文字列はファイルパスですが、代わりに URI として処理。Alias、Redirect、ScriptAlias ディレクティブの場合指定。
S (Skip)指定した数のルールをスキップ。
T (Type)ターゲットファイルを強制的に指定した MIME-type にする。

正規表現パターン一覧

パターンマッチ時に正規表現を使用する。

.任意の1文字 にマッチ
★よく使う表現
(.*)\.gif 任意の文字が0回以上ある場合。(要は何でもいいワイルドカードで、*.gif と同じ)。\.はドット"."をエスケープ処理している。
+直前の文字が 1回以上 繰り返す場合にマッチ。
"spe+ch" は"sp"で始まり"e"が1回以上あり、"ch"で終わる、 "spech" や "speech" にはマッチするが "spch" にはマッチしない。
*直前の文字が 0回以上 繰り返す場合にマッチ。
"spe*ch" は "sp"で始まり"e"が0回以上あり、"ch"で終わる、"spech" や "speech" や "spch" にマッチ。
?【1:正規表現】直前の文字が 0個か1個 ある場合にマッチ。
"spe?ch" は "sp"で始まり"e"が0回か1回だけあり、"ch"で終わる、"spech" や "spch" にマッチするが "speech" にはマッチしない。

【2】クエリ文字をリライトやリダイレクトに付加しない
RewriteRule ^old/hello.html$ /new/hello.html? [R=301]
以前のクエリは破棄して、新しいクエリを付加する場合(?の後に記述)
RewriteRule ^old/hello.html$ /new/hello.html?user_id=100 [R=301]
以前のクエリも新しいクエリを付加する場合 (QSAフラグ)
RewriteRule ^old/hello.html$ /new/hello.html?user_id=100 [R=301, QSA]
^直後の文字列が行の 先頭 にある場合にマッチ。
"^example\.com" は行の先頭に "example.com" の文字がある場合にマッチ。
^blog/hello\.html$は先頭に"blog/hello.html"で始まり、終わりに何もない文字列とマッチする。
$【1:正規表現】直前の文字列が末尾 にある場合にマッチ。
"/test/index$" は行の末尾に "/test/index" の文字がある場合にマッチ。

【2:後方マッチ記号】^(.*)とマッチした文字列が$1
.htaccessが/bbbにある時、
https://aaa.com/bbb/ccc.htmlでアクセスが来て(.*) にマッチするのはccc.htmlなので、
$1はccc.htmlを表す。
RewriteRule ^(.*)$ abc/$1 は
https://aaa.com/bbb/abc/ccc.htmlに 転送する
$1はccc.htmlなのでabc/$1はabc/ccc.htmlとしてくっつける。
-置換を禁止する。
アクセス禁止の時等。
!否定。 文字列とマッチするものは排除する。
|OR
"index|test" は "index" と "test" にマッチします。
\直後の "正規表現において特別な意味を持つ" 文字を エスケープ する。
^www\. で"www."で始まる文字列。
[]角括弧に含まれる文字のいずれか1つにマッチ。
[abcXYZ01] は "a" , "b" , "c" , "X" , "Y" , "Z" , "0" , "1" にマッチ。

角括弧内の文字を "-" を使って範囲指定のマッチする。
[a-cX-Z0-3 は "a" , "b" , "c" , "X" , "Y" , "Z" , "0" , "1" , "2" , "3" にマッチ。

【注意】角括弧内の^は角括弧外で使う^と意味が異なる。
角括弧内の先頭に "^" を使って含まれない文字のマッチもできる。
[^abc] は "a" , "b" , "c" 以外の文字にマッチ。
()【1】文字の集合を1つの文字列として扱う。
(speech)+ は "speech" を1つの単位として評価するため "speech" にマッチ。
また、マッチング文字列は後述する "後方参照" として利用できる。

【2】|と併用
"test(2|3)"とするとtest2とtest3にマッチ。
{n}直前の文字、または文字列の繰り返し数がn個の場合のみマッチ判定する。
{n,m}直前の文字、または文字列の繰り返し数がn個~m個の間の場合マッチ判定する。
a{3} は a が3桁、つまり "aaa" にマッチします。
a{3,5} は a が3~5桁、つまり "aaa" , "aaaa" , "aaaaa" にマッチします。
a{3,} は a が3桁以上にマッチします。
\d
[0-9]
すべての数字
\D
[^0-9]
すべての数字以外の文字
\s
[ \t\f\r\n]
垂直タブ以外のすべての空白文字
\S
[^ \t\f\r\n]
すべての非空白文字
\w
[a-zA-Z_0-9]
英数字、アンダーバー
\W
[^a-zA-Z_0-9]
英数字、アンダーバー以外の文字
[:digit:]
[0-9]
すべての数字
[:lower:]
[a-z]
小文字のアルファベット
[:upper:]
[A-Z]
大文字のアルファベット
[:alpha:]
[a-zA-Z]
アルファベット
[:xdigit:]
[0-9A-Fa-f]
16進数で使われる数字とアルファベット
[:alnum:]
[a-zA-Z0-9]
アルファベットと数字
[:punct:]
[.,!?:...]
句読点文字
[:cntrl:]
(なし)
制御文字
[:blank:]
[ \t]
空白文字とタブ
[:graph:]
[^\n\r\f\v]
印字文字
[:space:]
[ \t\n\r\f\v]
改行を含む空白文字
<文字列として比較、辞書順で小さい場合にtrue

RewriteCond %{TIME} <20211231235959
RewriteRule ^(.*)$ http://ichiri.biz/$1 [R=301,L]
RewriteCond %{TIME} >=20220101000000
RewriteRule ^(.*)$ http://ichiri.biz/new/$1 [R=301,L]
>文字列として比較、辞書順で大きい場合にtrue
=文字列として比較、辞書順で等しい場合にtrue
<=文字列として比較、辞書順で等しいか小さい場合にtrue
>=文字列として比較、辞書順で等しいか大きい場合にtrue
-eq数値として比較、等しい場合にtrue
-ge数値として比較、等しいか大きい場合にtrue
-gt数値として比較、大きい場合にtrue
-le数値として比較、等しいか小さい場合にtrue
-lt数値として比較、小さい場合にtrue
-ne数値として比較、値が異なる場合にtrue(!-eqと同じ)
-d実際に存在しディレクトリだった場合にtrue
-f実際に存在しファイルの場合にtrue
-Fアクセス可能な有効なパスの場合にtrue
-h-l と同じ
-lシンボリックリンクの場合にtrue
-L-l と同じ
-sサイズが0でないファイルの場合にtrue
-Uアクセス可能な有効なURLの場合にtrue
-x実行権限がある場合にtrue

サーバー変数一覧

Typeサーバー変数
Server Variable
例、説明
%{HTTP:header}%{HTTP:UPGRADE}指定したHTTPリクエストヘッダの値
%{HTTP:header}%{HTTP:CONNECTION}指定したHTTPリクエストヘッダの値
%{HTTP:header}%{HTTP:Accept-Encoding}gzip,%20deflate
%{HTTP:header}%{HTTP:Accept-Language}ja,en;q=0.9,en-US;q=0.8
%{ENV:variable}%{ENV:環境変数名}指定した環境変数の値

SetEnvIf Request_URI "\.(gif|jpe?g|png)$" request_is=image

SetEnvIf????
%{SSL:variable}指定したSSL環境変数の値指定したSSL環境変数の値
connection & request%{SCRIPT_FILENAME}REQUEST_FILENAMEと同じ
c:/pg/Apache/Apache24/htdocs/old/test.html
connection & request%{REQUEST_METHOD}HTTPリクエストメソッド(GET、POST、PUTなど)
connection & request%{REMOTE_USER}認証されたユーザー名 (基本認証利用時)
connection & request%{REMOTE_PORT}ポート番号
connection & request%{REMOTE_IDENT]IDENTによるユーザー名
connection & request%{REMOTE_HOST}リモートホストのIPアドレス
connection & request%{REMOTE_ADDR} RewriteCond %{REMOTE_ADDR} !=XXX.XXX.XXX.1
# 特定IPアドレス以外は次へ
connection & request%{QUERY_STRING}クエリ文字列 num=10
connection & request%{PATH_INFO}パス情報
connection & request%{IPV6}IPv6ならon
connection & request%{CONTEXT_PREFIX}
connection & request%{CONTEXT_DOCUMENT_ROOT}
connection & request%{CONN_REMOTE_ADDR}接続のPeer(相手)のIPアドレス
connection & request%{AUTH_TYPE}認証方式
date and time%{TIME} 現在の日付と時刻(20211231235959)

RewriteCond %{TIME} <201305010900.*

# 2013年05月01日 09:00 までは
date and time%{TIME_YEAR}現在の年(2021)
date and time%{TIME_WDAY}現在の曜日(0,1,...6) 0=Sunday
date and time%{TIME_SEC}現在の秒(00,01,...,59)
date and time%{TIME_MON}現在の月(01,02,...,12)
date and time%{TIME_MIN}現在の分(00,01,...,59)
date and time%{TIME_HOUR}現在の時(00,01,...,23)
date and time%{TIME_DAY}現在の日(01,02,...,31)
server internals%{SERVER_SOFTWARE}Webサーバのソフトウェア情報
Apache/2.4.43%20(Win64)%20PHP/7.4.
server internals%{SERVER_PROTOCOL}リクエストのプロトコル名とバージョン
HTTP/1.1
server internals%{SERVER_PORT}サーバーのポート番号
server internals%{SERVER_NAME}サーバー名
server internals%{SERVER_ADMIN}サーバー管理者情報
server internals%{SERVER_ADDR}サーバアドレス
server internals%{SCRIPT_USER}スクリプトオーナーのユーザー名
server internals%{SCRIPT_GROUP}スクリプトグループのグループ名
server internals%{DOCUMENT_ROOTドキュメントルートのパス

c:/pg/Apache/Apache/htdocs
HTTP headers%{HTTP_USER_AGENT} ${HTTP_USER_AGENT} (iPod|iPhone|Android.*Mobile|Windows\ phone)
# 携帯電話であった場合
HTTP headers%{HTTP_REFERER}参照元のURL
HTTP headers%{HTTP_PROXY_CONNECTION}プロキシの接続形態
HTTP headers%{HTTP_HOST}リクエスト先のサーバ名
HTTP headers%{HTTP_FORWARDED}プロキシのURI
HTTP headers%{HTTP_COOKIE}クッキーに関するデータ
HTTP headers%{HTTP_ACCEPT}クライアントがサポート可能なMIMEタイプ
Specials%{THE_REQUEST} "GET /index.html HTTP/1.1" 等のフルHTTPリクエスト文
GET%20/old/hello.html%3fnum=10%20HTTP/1.1
Specials%{REQUEST_URI}リクエストのクエリとドメインを除くURI("/index.html"等)

#画像の場合は除外
RewriteCond %{REQUEST_URI} !\.(css|jpe?g|png|js|gif|swf|ico)$
Specials%{REQUEST_SCHEME}リクエストのスキーム
通常"http"か"https"
Specials%{REQUEST_FILENAME} ファイルやスクリプトのフルのローカルファイルパス

RewriteCond %{REQUEST_FILENAME} !-d
Specials%{IS_SUBREQ}現在sub-requestが実行されていたらtrueが入っている。
Specials%{HTTPS}SSL/TLSの場合はon が入っている。
RewriteCond %{HTTPS} off
# HTTPS通信では無かった場合
Specials%{API_VERSION}Apache httpdモジュールAPIのバージョン

その他

Lフラグは.htaccessでは無視される

以下の様に[L]フラグを付けると、.htaccess内でなければ、最初のindex2.htmlを出力してindex3.htmlは出力されないが、.htaccess内では[L]フラグは無視されるので、index1.htmlがindex2.htmlに置き換わり、下の行に移行して、置き換わったindex2.htmlがindex3.htmlに置き換わって最終出力されるので.htaccess内は注意が必要。

# index1.html → index2.html に書き換わった時点で終了しない 
RewriteRule index1.html index2.html [L] 
RewriteRule index2.html index3.html [L]

.htaccessで無視される例

  • SSLProxyEngine on (httpd.condf等で指定する)
  • RewriteRuleのLフラグ

mod_rewriteの記述場所

 httpd.conf, VirtualHost, Directory, .htaccess

.htaccessに記述する場合はhttpd.confにAllowOverride FileInfoが設定されている必要がある。

参考

BlueSilverCatさんの『数値とマッチする正規表現』<=沢山例があり

コメント

  1. 3箇所 .htacess になってますね。

    • ご指摘大変ありがとうございます。 早速修正いたしました。