サーバーに「.htaccess」というファイルを置いて、そこに設定を記述しておくと、アクセス制限を掛けたり、アクセスしてきた人を別のURLに飛ばしたりできるわけですが。 サーバー引っ越しの際に、検索ランキングを落とさないようにする301リダイレクトもこれで行うわけですが。 それについて、「こう書けばいいよ」ってコピペでOKな設定の書き方を公開してくれている人は多いのですが、基本的なルールや書き方については意外と解説が少なかったので、自分なりに調べた事のまとめを覚え書きとして記録しておきます。
.htaccessはどこに置くの?
各フォルダに置きます。 下層フォルダに「.htaccess」がない場合は、上位のフォルダの「.htaccess」の設定が下層フォルダにも継承されます。 下層フォルダに「.htaccess」があった場合は、より下層の設定が上書きされます(有効となります)。
書き方が二種類あるのは何?
リダイレクトは、検索すると、書き方が二種類出てきます。 ひとつは
redirect permanent /hogehoge /fugafuga
みたいな、一行で済むシンプルな書き方。 もう一つは
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(.*)$ https://fugafuga.com/$1 [R=301,L]
</IfModule>
みたいな、複数行にわたる、なんだか複雑な書き方。 これは、前者はサーバーの基本的な機能を使った書き方、後者は「mod_rewrite」という拡張機能を使った場合の書き方だそうで。 「mod_rewrite」はあくまで拡張機能なので、その機能がインストールされていないサーバーでは使えません。(今時はほとんどのサーバーで使えると思いますが。) 前者はシンプルですが、複雑な設定ができません。後者は複雑な設定が可能になります。 URLまるごと転送のような単純な設定であれば、前者のシンプルな書き方で問題ありません。
基本的な機能を使った書き方
redirect 「オプション」 「転送元url」 「転送先url」
のように書きます例
redirect /hogehoge /fugafuga
であれば、/hogehoge という url にアクセスしてきた場合に、/fugafuga という url(ディレクトリ)に転送されます。↓だと
redirect permanent /hogehoge/abc.html /fugafuga/def.html
/hogehoge/abc.html にアクセスすると /fugafuga/def.html に転送されます。↓だと
redirect permanent / http://fuga.com/
アクセスしてきた人すべてが、http://fuga.com/ に転送されます。 ※ただし、この場合、アクセス元と同名ファイルに転送されるようです。 通常、ファイル名なしの url を指定した場合、index.html が表示されますが、この書き方だと、アクセスしてきた url が http://hogehoge.com/abc.html だった場合、http://hogehoge.com/abc.htmlがあればそこに転送されますが、なかった場合、index.html は表示されず、404エラーとなります。 ☆実はファイル名なしの url にアクセスした場合にどのファイルを表示するかも「.htaccess」によって変更できます。デフォルト(.htaccessなし)の状態では、サーバーの初期設定が継承されて、index.html が表示されているわけですね。 また、オプションに「permanent」をつけると恒久的転送(301リダイレクト)となります。例
redirect permanent /hogehoge /fugafuga
例
redirect permanent /hogehoge/abc.html /fugafuga/def.html
例
redirect permanent / https://fugafuga.com/
オプションを省略すると「temp」を指定したのと同じ、一時的な転送と言う意味になります(302リダイレクト)
(オプションは他に「seeother」「gone」などがあるようです。)
「mod_rewrite」を使った書き方
1) <IfModule mod_rewrite.c>
2) RewriteEngine on
3) RewriteRule ^(.*)$ https://fugafuga.com/$1 [R=301,L]
4) </IfModule>
まず、一行目及び4行目の <IfModule mod_rewrite.c> </IfModule> ←これなに? これは、「mod_rewrite」が利用できるかチェックし、もし機能が利用できないサーバーの場合には、このタグで囲まれた間の記述はすべて無視される、という意味になります。 もし「mod_rewrite」の機能がないのに、このタグで挟まずに記述してしまうと、エラーになってしまうようです。
2行目、「RewriteEngine on」これは、「mod_rewrite」の機能を有効化(オンに)すると言う意味で、一度記述すれば何度も書く必要はないようです。
三行目、冒頭に書いてある「RewriteRule」は処理内容を示しています。この場合は url を書き換え(Rewrite)するルールと言う意味なのでしょうね。
RewriteRule 「転送元url」 「転送先url」
という記述の仕方をします、redirectと書き方は同じですね。
次に続く「^(.*)$ https://fugafuga.com/wp/$1」の部分、これは、「正規表現」が使われています。PHPプログラミングで使われる正規表現に準拠しているようで、秀丸エディタの正規表現とは微妙に違っている部分がありますが、よく似ているので理解しやすかったです。 正規表現はすべてを数行で説明できるものではないですが、簡単に 「^」(キャレット)は行頭を意味します。 「.」(ドット)は何らかの文字、「*」は直前の文字の無制限連続の意味。 「^.*」は冒頭から何らかの文字が続いていると言う意味になるわけです。 「$」マークは行の終端を意味します。(ただし改行は含みません) 「 ^.*$ 」と書くと、行頭から終端までの何らかの文字の連続、と言う意味ですから、つまり一行全部、と言う意味になるわけです。 これをアクセスしてきた url に適用するわけですから、アクセスしてきた url のすべてを意味する事になります。 例文には括弧がついていますが、これは検索文字列を区切る場合に使用します。 これは「タグ付き正規表現」とか「後方参照」とかいうようですが、具体的には、括弧でくくった内容を、後に出てくる「$1」「$2」などで引用出来る機能です。 実例を見れば分かると思います。 「桜は咲いたが梅はまだ」 という文章があった場合に、検索条件に 「(桜)は咲いたが(梅)はまだ」 として、置き換え内容に 「$2は咲いたが$1はまだ」 とすると、置き換えの結果として 「梅は咲いたが桜はまだ」 とする事ができるわけです。 ($の後の数字が、何番目の括弧かを表す) 括弧は、文章内のグループ化、区切りのマーキングに過ぎないと考えて良い感じでしょうか。それを、置き換え後に何番目の括弧かを指定することで引用できるわけです。 つまり、「^(.*)$ https://fugafuga.com/$1」の部分の意味は、アクセスしてきた url 「^(.*)$」を「https://fugafuga.com/$1」に置き換えると言う意味で $1が付いていますので、検索文字のカッコ内(つまりこの場合はリクエストのあった url すべて)を「https://fugafuga.com/」の後に付ける、と言う意味になるわけですね。
※ $+数字 で前の条件式のカッコ内を引用できるのはRewriteRuleだけで、RewriteCondの条件式から引用した場合は %+数字 となるようです。このへんのルールはかなり難しくなってくるので、正規表現と「mod_rewrite」について詳しく勉強が必要ですね。
最後の [R=301,L]の部分はフラグと言って、例えば「NC」と書いた場合は「No Case」つまり大文字と小文字を区別しないと言う意味になります。 R=301は恒久的なリダイレクトであることを意味します(permanentと同じ) 「L」はラストの意味で、この条件にマッチした場合は以降の処理を行わないという意味になります。 (使用できるフラグ一覧表は文末資料参照)
これだけなら、「mod_rewrite」の機能を使わなくても「redirect」だけで同じ事ができますが、RewriteRule の前に 「 RewriteCond 」を記述することで、複雑な条件指定ができるようになります。
RewriteCond %{変数名} 条件
RewriteCond %{変数名} 条件
RewriteRule URL置き換えの記述
※明確な解説が見つからないのですが、変数は %{ 変数名 } のように%{}で括る事になっているようですね。(使用できる変数一覧表は文末資料参照) 例えば
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
と書かれている場合 「-f」はファイルが存在するかどうかを判定 「-d」はディレクトリが存在するかどうかを判定 「!」は結果を逆にすると言う意味 つまり、 (1)ファイルが存在しない (2)ディレクトリが存在しない 条件にマッチした場合に、次の行の RewriteRule を適用すると言う意味になります。 実はこれ、WordPressが自動的に挿入するリダイレクト設定ですね。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
WordPressでは、とりあえずリクエストはすべて「 /index.php 」で受けておいてから処理をするようになっているのだそうで。。。
条件にマッチしない場合は次行の RewriteRule は適用されません。 ただし、さらに続けて RewriteRule が書かれている場合は、二行目以降の RewriteRule は適用されます。( RewriteCond は直後に続く RewriteRule ひとつのみの条件設定となっている。) 下記のように書かれていた場合
RewriteCond %変数名 条件(A)
RewriteCond %変数名 条件(B)
RewriteRule URL置き換え指示(1)
RewriteRule URL置き換え指示(2)
条件(A)及び(B)に両方マッチした場合は置き換え指示(1)が適用され、続けて置き換え指示(2)が適用される。 条件(A)(B)いずれか一方でもマッチしなかった場合は、置き換え指示(1)は無視され、置き換え指示(2)だけが適用される。 条件にマッチしたらそこで終了したい場合は、フラグの「L」を使う。
※フラグ「L」は、終了ではなく、実は終了ではなく、最初から再評価となるとの解説が。 完全にそこで終了させたい場合は、「L」の代わりに「END」を使う(使える場合)とのこと。 なるほど。。。
.htaccess に RewriteRule 書くときは、[L]フラグをつけてもそこで終了しないかもよ?って話。 - Qiita
`.htaccess`で`RewriteRule`書くときに、安易に`[L]`フラグを使うと思ったように動かないかもしれない。仕組みを理解して使えば単純な事なんですがね!# .htaccess でアクセスを振り分けたい!Ap...…
qiita.com
RewriteCond で使用できる変数一覧
グループ | 変数名 | 値・意味 |
---|---|---|
HTTP ヘッダ | HTTP_USER_AGENT | ユーザーエージェント |
HTTP_REFERER | 参照元URL | |
HTTP_COOKIE | クッキー情報 | |
HTTP_FORWARDED | プロキシ情報 | |
HTTP_HOST | サーバーのホスト名 | |
HTTP_PROXY_CONNECTION | プロキシを経由しているか否か | |
HTTP_ACCEPT | ブラウザの言語タイプ | |
コネクション & リクエスト | REMOTE_ADDR | リモートアドレス |
REMOTE_HOST | リモートホスト名 | |
REMOTE_USER | リモートユーザー名 (基本認証利用時) | |
REMOTE_IDENT | リモートユーザーのID | |
REQUEST_METHOD | リクエストメソッド | |
SCRIPT_FILENAME | スクリプトファイル名 | |
PATH_INFO | パス情報 | |
QUERY_STRING | クエリ文字列 | |
AUTH_TYPE | 認証タイプ | |
サーバ内部変数 | DOCUMENT_ROOT | ドキュメントルートのパス |
SERVER_ADMIN | サーバー管理者情報 | |
SERVER_NAME | サーバー名 | |
SERVER_ADDR | サーバーのアドレス | |
SERVER_PORT | サーバーのポート番号 | |
SERVER_PROTOCOL | プロトコルバージョン | |
SERVER_SOFTWARE | サーバーソフトウェア | |
システム関連 | TIME_YEAR | 年 |
TIME_MON | 月 | |
TIME_DAY | 日 | |
TIME_HOUR | 時 | |
TIME_MIN | 分 | |
TIME_SEC | 秒 | |
TIME_WDAY | 曜日 (0:日 ~ 6:土) | |
TIME | 年月日時分秒 (例:20130123123456) | |
特別なもの | API_VERSION | APIバージョン |
THE_REQUEST | リクエスト文字列 | |
REQUEST_URI | リクエストURI | |
REQUEST_FILENAME | リクエストされたファイル名 | |
IS_SUBREQ | サブリクエストか否か | |
HTTPS | HTTPSでのアクセスか否か |
資料
RewriteRuleのフラグ一覧フラグ | 意味 | 説明 |
---|---|---|
C | Chain | このルールにマッチしたら、次のルールを評価 |
F | Forbidden | アクセス禁止(403-Forbidden)。[L]フラグと同様、以降のルールは無視される |
G | Gone | 削除(410-Gone) |
L | Last | マッチしたらRewriteを止めます。以降のルールは無視! |
NC | No Case | 大文字小文字を無視 |
NE | No Escape | ".", "?", "%"などの特殊文字が"%25″のようにエンコードされるのを防ぐ |
OR | Or | RewriteCondを複数指定する場合のor指定。指定なしならAND |
PT | Path Through | Rewriteを終了し、それ以外の処理に移行 |
R | Redirect | 指定したURLにリダイレクト。[R=303]のようにリダイレクトコードも付加できる。[L]フラグと同様、以降のルールは無視される |
コメント