htaccessによるリダイレクト徹底解説

59
2013/09/29 WordBench京都 Cherry Pie Web 川井昌彦 .htaccessによるリダイレクト徹底解説 ~無限ループで100倍返しされないために~

Upload: masahiko-kawai

Post on 20-Dec-2014

41.484 views

Category:

Technology


0 download

DESCRIPTION

2013年9月29日 WordBench京都

TRANSCRIPT

Page 1: htaccessによるリダイレクト徹底解説

2013/09/29

WordBench京都

Cherry Pie Web 川井昌彦

.htaccessによるリダイレクト徹底解説 ~無限ループで100倍返しされないために~

Page 2: htaccessによるリダイレクト徹底解説

2

自己紹介●川井昌彦(かわいまさひこ) @sakuragi_kei

 東京の制作会社で24年間勤めた後、

 京都府舞鶴市に帰郷してフリーランスで活動中

 実は、DTPのほうが経験が長いです

  (このスライドも InDesign で作っています)

 実は、MovableTypeのほうが経験が長いです

 小桜インコ・シロハラインコ・黒い柴犬のパパ

 Cherry Pie Web http://www.cherrypieweb.com

Page 3: htaccessによるリダイレクト徹底解説

3

本日の予定1. リダイレクトとは

2. 基本のリダイレクト

3. mod_rewrite によるリダイレクト

4. WordPressが書き出すリダイレクトを見てみよう

5. まとめ

・・・実際は、こんなふうに

     キレイにはまとまっていません・・・

Page 4: htaccessによるリダイレクト徹底解説

4

リダイレクトとはウェブページへの訪問者を、自動的に他のページへ移動させること

ウェブページなどの移動の通知に使われることが多い

郵便局の自動転送というより、

 ドアに、「引っ越しました」の

  張り紙があるようなイメージ

Page 5: htaccessによるリダイレクト徹底解説

5

たとえば・・・

1. ウェブページのファイル名が変わった

2. ウェブページを他のディレクトリに移動した

3. ドメイン名が変わった

4. 一部のページに、ユーザーがアクセスできないようにする

5. index.htmlあり/なし、wwwあり/なしなどを統一する

                        ・・・など

Page 6: htaccessによるリダイレクト徹底解説

6

リダイレクトの指定方法1. htmlの、metaタグ

2. JavaScriptの、location.href=、または、location.replace()

3. PHPなどで、HTTPヘッダーを出力

 上記3つは、

  アクセスされるすべてのページに指定しておかなければならない

4. Webサーバーの設定

httpd.conf または、 .htaccess に指定する

ページへのアクセス自体を制御できる

Page 7: htaccessによるリダイレクト徹底解説

7

.htaccess の有効範囲

.htaccess が置かれたディレクトリから下位すべてのディレクトリに有効

ただし、下位ディレクトリにも

.htaccess が置かれていた場合、

 競合する設定は、

  下位のものが有効

example.com .htaccess index.html test1.html

sub1 .htaccess index.html subtest1.html

sub2 index.html subtest2.html

Page 8: htaccessによるリダイレクト徹底解説

8

では、さっそくサンプルをいくつか

Page 9: htaccessによるリダイレクト徹底解説

9

ウェブページのファイル名を変えた

Redirect:リダイレクトを示す

Permanent:301リダイレクト(恒久的なリダイレクト)

/test1.html:古いファイル名  ドキュメントルートからのパスを指定する

http://example.com/test2.html:新しいファイル名  絶対URLを指定する

Redirect Permanent /test1.html http://example.com/test2.html

Page 10: htaccessによるリダイレクト徹底解説

10

ドキュメントルートとは?ブラウザからドメイン名でアクセスしたときのサーバー上の位置

(例) /var/user_name/public_html/ ←ここが、/ (ルート)になる

ファイルのドキュメントルートからのパスは、

 URLからドメイン名をとったものと、だいたい同じ

サブドメインやマルチドメインの時は、

 サブディレクトリがルートになることもある

http://example.com/test1.html

Page 11: htaccessによるリダイレクト徹底解説

11

絶対URLとは?http://www.example.com/test2.html

 のようにドメイン名を省略しないURL

※相対パスで指定できない!

※同じドメイン内でも省略できない!

Page 12: htaccessによるリダイレクト徹底解説

12

301リダイレクトとは?完全に引っ越したとき(元に戻る予定はない)

302リダイレクトとは?メンテナンスなどで、一時的に移動しているとき

Page 13: htaccessによるリダイレクト徹底解説

13

301リダイレクトにするメリット301リダイレクトと指定した場合、検索エンジンは、

元のページから新しいページに移動したことを、

検索結果に反映してくれるようになる。

また、元のページの評価を、

 新しいページに引き継いでくれる。

ただし、

 「はてブ」や「いいね」は

  自動で引き継がれたり

        しません。

PageRankの 引き継ぎでーす

Page 14: htaccessによるリダイレクト徹底解説

14

ディレクトリを移動した

oldディレクトリ以下へのアクセスはすべて、

 newディレクトリ以下へリダイレクト

Redirect permanent は、Redirect 301 と書いても良い

【注意!】

リダイレクト元とリダイレクト先のドメインが同じで、

         ディレクトリが親子関係だとエラーになる

                         (後述します)

Redirect 301 /old/ http://example.com/new/

Page 15: htaccessによるリダイレクト徹底解説

15

ドメインを変えた

全てのアクセスを、http://example.com へリダイレクト

【注意!】

リダイレクト元とリダイレクト先のドメインが同じだとエラーになる

                         (後述します)

Redirect 301 / http://example.com/

Page 16: htaccessによるリダイレクト徹底解説

16

負荷軽減のため画像ファイルだけを 他のサーバーから読み込む

RedirectMatch:パターンマッチを使用したリダイレクト

301:301 リダイレクト

(.*¥.(jpg|gif|png))$:元の画像ファイル名

http://another-img.com$1:読み込む画像ファイル名

RedirectMatch 301 (.*\.(jpg|gif|png))$ http://another-img.com$1

Page 17: htaccessによるリダイレクト徹底解説

17

正規表現の例(.* ¥.(jpg|gif|png))$ http://another-img.com$1

. :全ての文字

* :0回以上の繰り返し

( ):ブロックを指定

¥.:ドット  「. 」 は、正規表現ではすべての文字を示す   ドットそのものを表すときは ¥をつける(エスケープする)

(jpg|gif|png):jpg,gif,pngのいずれか

$:行の終わり

$1:1つめのブロック

Page 18: htaccessによるリダイレクト徹底解説

18

リダイレクトは、無限ループにならないように注意!

たとえば、こんな設定で

リダイレクト元とリダイレクト先のドメインが同じだったら・・・

つまり・・・

http://amachan.com へのすべてのアクセスを、

http://amachan.com/je/ へリダイレクトしたいとしたら・・・

Redirect 301 / http://amachan.com/je/

Page 19: htaccessによるリダイレクト徹底解説

19

http://amachan.com/index.php へのアクセスがどうなるか?

WordPressでよくある、

サブディレクトリにWordPressをインストールした場合のリダイレクトは、

この書き方ではできない!

  http://amachan.com/index.php

→ http://amachan.com/je/index.php → http://amachan.com/je/je/index.php → http://amachan.com/je/je/je/index.php → http://amachan.com/je/je/je/je/index.php → http://amachan.com/je/je/je/je/je/index.php

                   以下、無限ループ!!!!

Page 20: htaccessによるリダイレクト徹底解説

20

これまでの書き方の問題点1. 同じドメインで階層の違うディレクトリにリダイレクトをしようとすると、

無限ループが起きやすい

2. リダイレクト先はドメインを省略できないので、使いまわしができない

例えば、テスト環境から本番環境に持っていく時に、

リダイレクト先のドメイン名をすべて書き直さないといけない

ぐるぐる 回るよー

Page 21: htaccessによるリダイレクト徹底解説

21

mod_rewrite をつかったリダイレクトmod_rewriteは、

 Apache Webサーバーのモジュールで、

  サーバー内でURLの書き換えを行う

ブラウザの種類、リファラ、時間などの

あらゆる適用条件が指定できるなど

とても柔軟な指定が可能

Page 22: htaccessによるリダイレクト徹底解説

22

mod_rewite はインストールしてないと使えないサーバーに対して権限があるなら、追加でインストールすればよいが、

レンタルサーバーなどでは自分でインストールはできない。

安いレンタルサーバでは、インストールされていないところもある。

レンタルサーバーでは、「よくある質問」のコーナーに、

「mod_rewrite は使えますか?」という質問が掲載されていることが多い。

PHPが使えるなら、phpinfo() で調べる

Page 23: htaccessによるリダイレクト徹底解説

23

mod_rewrite がインストールされていなくても エラーが出ないようにするIfModule で囲んで、mod_rewriteがインストールされていないときは

実行されないようにしておく

<IfModule mod_rewrite.c>

・・・・

</IfModule>

Page 24: htaccessによるリダイレクト徹底解説

24

     では、さっそくサンプル

(注)以下、 <IfModule mod_rewrite.c> は省略します。

Page 25: htaccessによるリダイレクト徹底解説

25

ウェブページのファイル名を変えた

/test1.html → /test2.html

RewriteEngine on:リダイレクトの記述の開始

RewriteRule:リダイレクトのルール

RewriteEngine on

RewriteRule ^test1\.html$ test2.html

Page 26: htaccessによるリダイレクト徹底解説

26

RewriteRule・リダイレクト元の正規表現パターン

^test1¥.html$:  .htaccess と同じディレクトリにある test1.html に適用される

 .htaccess のあるディレクトリからの相対パス

mod_rewrite を使うときは、リダイレクト元のパスには / は不要

(リクエストされたURLから、.htaccess のあるパスまで削除されて、評価される)

RewriteEngine on

RewriteRule ^test1\.html$ test2.html

Page 27: htaccessによるリダイレクト徹底解説

27

 ^は行頭を表す

  → 同じディレクトリ以外には適用されない ×test/test1.html

 $は行末を表す

  → test1.htm には適用されない

 ¥.は、ドットを表す

  → .(ドット)はすべての文字という意味なので、

   ドット自体を表したいときは、¥をつける(エスケープする)

RewriteEngine on

RewriteRule ^test1\.html$ test2.html

Page 28: htaccessによるリダイレクト徹底解説

28

 と書くと、test/test1.html など、下位のディレクトリにも適用される

 と書くと、test1.htm、test1.html の両方に適用される

^test1\.htm$ と書くと、test1.html には適用されない

RewriteEngine on

RewriteRule test1\.html$ test2.html

RewriteEngine on

RewriteRule ^test1\.htm test2.html

Page 29: htaccessによるリダイレクト徹底解説

29

・リダイレクト先の文字列

test2.html:  .htaccess と同じディレクトリにある test2.html にリダイレクト

 .htaccess のあるディレクトリからの相対パス、絶対パス、絶対URL

RewriteEngine on

RewriteRule ^test1\.html$ test2.html

Page 30: htaccessによるリダイレクト徹底解説

30

ディレクトリを移動した

oldディレクトリ以下へのアクセスを、newディレクトリにリダイレクト

^old/(.*)$:old以下へのすべてのアクセス

( ):ブロック

$1:( )ブロックの1つ目

RewriteEngine on

RewriteRule ^old/(.*)$ /new/$1

Page 31: htaccessによるリダイレクト徹底解説

31

ドメインを変えた

すべてのリクエストを、http://newserver.com/ にリダイレクトする

(̂.*)$:アクセスされたすべてのパターンにマッチ

( ):ブロック

$1:( )ブロックの1つ目

【注意!】リダイレクト元とリダイレクト先のドメインが同じだとエラーになる

RewriteEngine on

RewriteRule ^(.*)$ http://newserver.com/$1

Page 32: htaccessによるリダイレクト徹底解説

32

負荷軽減のため画像ファイルだけを 他のサーバーから読み込むRewriteEngine on

RewriteRule ^(.*)\.(jpg|gif|png)$ http://newserver.com/$1.$2

Page 33: htaccessによるリダイレクト徹底解説

33

トップページのURLを 「/index.html」ではなく「/」に統一

URLの正規化と言われるものの一つで、アクセス解析で重要

ほかにも、wwwあり/なし の統一などもできる

RewriteEngine on

RewriteRule ^index.html$ http://www.example.com/

Page 34: htaccessによるリダイレクト徹底解説

34

リダイレクトは、あちこちの .htaccess に書かない!.htaccess を下位のディレクトリにおくことがあるが、

リダイレクトをあちこちに書くと混乱の元!

・ mod_rewrite を使った場合、

リダイレクト元、リダイレクト先のパスは、

.htaccess が置かれたパスが基準となるので、ややこしい

・ 下位のルールが適用されると、上位のルールが適用されなくなる

Page 35: htaccessによるリダイレクト徹底解説

35

(例1).htaccess をルートディレクトリだけにおいたとき

/old/test1.html → /test2.html

リダイレクト先は、.htaccess が置かれているルートディレクトリになる

RewriteEngine on

RewriteRule ^old/test1\.html$ test2.html

Page 36: htaccessによるリダイレクト徹底解説

36

(例2).htaccess をoldディレクトリだけにおいたとき

/old/test1.html → /old/test2.html

リダイレクト先は、.htaccess が置かれているoldディレクトリになる

RewriteEngine on

RewriteRule test1\.html$ test2.html

Page 37: htaccessによるリダイレクト徹底解説

37

(例3).htaccess を複数のディレクトリにおいたときー 1

・ルートディレクトリ・・・(1)

・oldディレクトリ・・・(2)

/old/test2.html → /old/test3.html   (2)のルールのみ適用

/old/test1.html → 何も適用されない!  (2)のルールのみ適用

RewriteEngine on

RewriteRule ^old/test1\.html$ test2.html

RewriteEngine on

RewriteRule ^test2\.html$ test3.html

Page 38: htaccessによるリダイレクト徹底解説

38

リダイレクト指定が下位のディレクトリにもある場合

1. リクエストされたURLの最も下位の階層のリダイレクトを適用

2. リダイレクトされた結果のURLで、

改めて最も下位の階層のリダイレクトを適用

 上位の設定を下位の設定で

   上書きや追加をする

      わけではない!

Page 39: htaccessによるリダイレクト徹底解説

39

先ほどの例を見直すと・・・

・ルートディレクトリ・・・(1)

・oldディレクトリ・・・(2)

/old/test1.html がリクエストされたので、

oldディレクトリにあるリダイレクトの設定(2)が適用される。

ここに test1.html に対する設定がないので、ここで終わり

RewriteEngine on

RewriteRule ^old/test1\.html$ test2.html

RewriteEngine on

RewriteRule ^test2\.html$ test3.html

Page 40: htaccessによるリダイレクト徹底解説

40

(例4).htaccess を複数のディレクトリにおいたときー 2

・ルートディレクトリ・・・(1)

・oldディレクトリ・・・(2)

/test1.html → /test2.html

/old/test2.html → /test1.html → /test2.html

  (2)のルールでリダイレクトした結果、上位のURLになったので、

改めて上位のルール(1)のリダイレクトが適用される

RewriteEngine on

RewriteRule ^test1\.html$ test2.html

RewriteEngine on

RewriteRule ^test2\.html$ /test1.html

Page 41: htaccessによるリダイレクト徹底解説

41

複数のRewriteRule

/test1.html → /test2.html → /new/test2.html

RewriteRuleは、複数書ける

どれかにマッチすればリダイレクトされるので、もちろん、これも有効

/test2.html → /new/test2.html

RewriteEngine on

RewriteRule ^test1\.html$ test2.html

RewriteRule ^test2\.html$ new/test2.html

Page 42: htaccessによるリダイレクト徹底解説

42

RewriteBase

RewriteBase:リダイレクト後のパスのベース

 /test1.html → /old/test2.html となる

 /old/test1.html には適用されない

※RewriteBaseは、リダイレクト元には関係ない

RewriteEngine on

RewriteBase /old

RewriteRule ^test1\.html$ test2.html

Page 43: htaccessによるリダイレクト徹底解説

43

/old/test1.html に適用させるには、

リダイレクト元にディレクトリ指定が必要

RewriteEngine on

RewriteBase /old

RewriteRule ^old/test1\.html$ test2.html

Page 44: htaccessによるリダイレクト徹底解説

44

※Rewritebaseは、リダイレクト後の指定が相対パスの時のみ有効

 / をつけると絶対パスになるので RewriteBase は無効になる

/test1.html → /old/test2.html

/test1.html → /test2.html (RewriteBase無視)

RewriteEngine on

RewriteBase /old

RewriteRule ^test1\.html$ test2.html

RewriteEngine on

RewriteBase /old

RewriteRule ^test1\.html$ /test2.html

Page 45: htaccessによるリダイレクト徹底解説

45

特定ディレクトリへのアクセス拒否

oldディレクトリ以下へのアクセスを拒否する

[F]:403 Forbidden(アクセス権限がないエラー)を返す

RewriteRule のリダイレクト先を「-」とすると、リダイレクトしない

RewriteEngine on

RewriteRule ^old/.* - [F]

Page 46: htaccessによるリダイレクト徹底解説

46

ieからアクセスされたときだけ 違うファイルにリダイレクトする

RewriteCond:条件にマッチした時、RewriteRuleを適用する

%{HTTP_USER_AGENT}:環境変数(ユーザーエージェントを得る)

[NC]:大文字小文字を区別しない

RewriteEngine on

RewriteCond %{HTTP_USER_AGENT} MSIE [NC]

RewriteRule ^test1\.html$ test2.html

Page 47: htaccessによるリダイレクト徹底解説

47

使える環境変数HTTP_USER_AGENT / HTTP_REFERER / HTTP_COOKIE / HTTP_FORWARDED HTTP_HOST / HTTP_PROXY_CONNECTION / HTTP_ACCEPT

REMOTE_ADDR / REMOTE_HOST / REMOTE_USER / REMOTE_IDENT 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 / TIME

API_VERSION / THE_REQUEST / REQUEST_URI / REQUEST_FILENAME IS_SUBREQ

Page 48: htaccessによるリダイレクト徹底解説

48

RewriteCondを使った例・2013年12月28日~ 2014年1月3日までの間だけリダイレクトする

RewriteCondを複数書いたときは、AND条件(すべて満たしたとき)

比較に使えるのは、< > = ( >= みたいなのは使えない)

比較演算子の後にスペースを入れないこと

RewriteEngine on

RewriteCond %{TIME_YEAR}%{TIME_MON}%{TIME_DAY} >20131227

RewriteCond %{TIME_YEAR}%{TIME_MON}%{TIME_DAY} <20140104

RewriteRule ^test1\.html$ test2.html

Page 49: htaccessによるリダイレクト徹底解説

49

・iPhoneまたはiPadからアクセスされたときだけリダイレクトする

次の条件とOR条件(いずれかを満たすとき)にしたいときは、

[OR]フラグをつける

RewriteEngine on

RewriteCond %{HTTP_USER_AGENT} iPhone [NC,OR]

RewriteCond %{HTTP_USER_AGENT} iPod [NC]

RewriteRule ^test1\.html$ /test2.html

Page 50: htaccessによるリダイレクト徹底解説

50

・特定のIPアドレスからのアクセスを拒否

IPアドレスが 123.456.789.012 または 012.345.678.901 から

アクセスされたら、403 Forbidden を返す

[F]:403 Forbidden(アクセス権限がないエラー)を返す

RewriteRule のリダイレクト先を「-」とすると、リダイレクトしない

RewriteEngine on

RewriteCond %{REMOTE_ADDR} ^123\.456\.789\.012$ [OR]

RewriteCond %{REMOTE_ADDR} ^012\.345\.678\.901$

RewriteRule ^.*$ - [F]

Page 51: htaccessによるリダイレクト徹底解説

51

・特定のIPアドレス以外からのアクセスを拒否

IPアドレスが 012.345.678.901 以外から

アクセスされたら、403 Forbidden を返す

!:否定(条件を満たさないときに有効)

RewriteEngine on

RewriteCond %{REMOTE_ADDR} !^012\.345\.678\.901$

RewriteRule ^.*$ - [F]

Page 52: htaccessによるリダイレクト徹底解説

52

・SSLによる通信を強制する

http;// でアクセスされても、

https:// に強制的に切り替えることで、SSLを有効にする

%{HTTPS} off:httpsでないアクセス

RewriteEngine on

RewriteCond %{HTTPS} off

RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

Page 53: htaccessによるリダイレクト徹底解説

53

WordPressでパーマリンク設定した時に作成されるリダイレクト<IfModule mod_rewrite.c>

RewriteEngine On

RewriteBase /wordpress/

RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule . /wordpress/index.php [L]

</IfModule>

Page 54: htaccessによるリダイレクト徹底解説

54

RewriteBaseで指定されているのは、

WordPressがインストールされたディレクトリ

RewriteRule のリダイレクト先を「-」とすると、リダイレクトしない

[L]:これ以降のルールを適用しない

ルートディレクトリのindex.phpにアクセスされたら

リダイレクトしないで終了

 → 次のルールによる無限ループが避けられる!

RewriteBase /wordpress/

RewriteRule ^index\.php$ - [L]

Page 55: htaccessによるリダイレクト徹底解説

55

-f:ファイルが実在すると true

-d:ディレクトリが実在すると true

アクセスされたファイルまたはディレクトリが実在する場合

 → そのままそのファイルを表示

アクセスされたファイルもディレクトリも実在しない場合

 → WordPressの index.php にリダイレクト

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule . /wordpress/index.php [L]

Page 56: htaccessによるリダイレクト徹底解説

56

Rフラグ

[R]:302リダイレクト  [R=301] とすれば、301リダイレクトになる

※Rフラグをつけないと、サーバー内部でリダイレクトが行われるので、

 アクセスした側はリダイレクトしたことがわからない!

→ ブラウザのアドレスバーはリダイレクト前のURLのまま!

RewriteEngine on

RewriteRule ^test1\.html$ test2.html [R]

Page 57: htaccessによるリダイレクト徹底解説

57

※Rフラグをつけると、

 アクセスした側が新しいパス(URL)にアクセスし直したように見える

→ ブラウザのアドレスバーがリダイレクト先のURLに変わる

SEOを考慮するなら、 [ R=301 ] は必須!

PageRankの 引き継ぎでーす

Page 58: htaccessによるリダイレクト徹底解説

58

リダイレクトのまとめ・ 301リダイレクトと302リダイレクトを使い分けよう

(メンテナンス等以外は、301リダイレクトを使う)

・ 無限ループに注意

・ リダイレクトの記述は、できるだけ1か所にまとめよう

・ 正規表現を勉強しよう

Page 59: htaccessによるリダイレクト徹底解説

59

  ご清聴ありがとうございました。