URL リダイレクトは、 URL 転送とも呼ばれ、ページ、フォーム、ウェブアプリケーション全体などに二つ以上の URL のアドレスを与えるテクニックです。 HTTP では特別な種類の応答である HTTP リダイレクトを提供し、サイトをメンテナンスしている間の一時的なリダイレクト、サイトの構成を変更した後も外部のリンクを機能させるための恒久的なリダイレクト、ファイルをアップロードしているときの進捗を示すページなど、様々な目的のためにこの操作を行います。

原理

HTTP では、要求に対してリダイレクトという特別な応答を送信することによって、サーバーがリダイレクトを発生させます。 HTTP リダイレクトは、 3xx のステータスコードを持つ応答です。ブラウザーはリダイレクト応答を受け取ると、提供された新たな URL を使用して直ちに読み込みを行います。ほとんどの場合、リダイレクトはわずかなパフォーマンスへの影響を除けばユーザーに対して透過的です。

数種類のリダイレクトがあり、それらは一時的リダイレクト、恒久的リダイレクト、特殊リダイレクトの 3 つのカテゴリーに分類されます。

恒久的リダイレクト

これらのリダイレクトは、永久に続くことを意味します。元の URL は今後使用されず、新しい URL を使用すべきであることを示唆します。検索エンジンのロボットは検索インデックスで、リソースに関連付けられた URL を更新します。

コード テキスト メソッドの扱い 主な使用例
301 Moved Permanently GET メソッドは変更しません。
他のメソッドは GET に変更されるかもしれません。[1]
ウェブサイトの再編。
308 Permanent Redirect メソッドやボディは変更しません。 GET 以外のリンクや操作を含むウェブサイトの再編。

[1] 仕様ではメソッドの変更を意図していませんが、実際はメソッドを変更するユーザーエージェントが存在します。GET 以外のメソッドを使用するときの動作のあいまいさをなくすために、308 が定義されました。

一時的リダイレクト

正規の場所で要求したリソースにアクセスすることはできませんが、別の場所でアクセスできる場合があります。このような場合に、一時的なリダイレクトを使用できます。検索エンジンのロボットは、新たな一時的リンクを記録しません。一時的リダイレクトは、リソースを作成、更新、削除しているときに一時的な進捗ページを提供するためにも利用されます。

コード テキスト メソッドの扱い 主な使用例
302 Found GET メソッドは変更しません。
他のメソッドは GET に変更されるかもしれません。[2]
ウェブページは既知の理由により、一時的に使用できません。検索エンジンは自身のリンクを更新しません。
303 See Other GET メソッドは変更しません。
他のメソッドは GET変更します (ボディは失われます)。
ページの再読み込みによって操作が再度実施されることを防ぐために、PUTPOST の後のリダイレクトで使用します。
307 Temporary Redirect メソッドやボディは変更しません。 ウェブページは既知の理由により、一時的に使用できません。検索エンジンは自身のリンクを更新しません。サイトで GET 以外のリンクや操作を使用できる場合は、302 より推奨されます。

[1] 仕様ではメソッドの変更を意図していませんが、実際はメソッドを変更するユーザーエージェントが存在します。GET 以外のメソッドを使用するときの動作のあいまいさをなくすために、307 が定義されました。

特殊リダイレクト

前出の一般的なリダイレクトに加えて、特殊なリダイレクトが 2 つあります。304 (Not Modified) は、ページをローカルにキャッシュした (陳腐化した) 複製へリダイレクトします。また 300 (Multiple Choice) は、手動リダイレクトです。ブラウザーがウェブページとして表示するボディには使用可能なリダイレクトのリストがあり、ユーザーはひとつ選択してクリックします。

コード テキスト 主な使用例
300 Multiple Choice 多くはありません。ボディ内の HTML ページに選択肢の一覧があります。200 OK ステータスで提供されるかもしれません。
304 Not Modified キャッシュのリフレッシュ。キャッシュの値はまだ新鮮であり、使用できることを示します。

リダイレクトを指定する代替手段

HTTP リダイレクトは、リダイレクトを定義する唯一の手段ではありません。このほかに <meta> 要素を使用する HTML リダイレクトと、DOM を使用する JavaScript リダイレクトという 2 つの方法があります。

HTML リダイレクト

HTTP リダイレクトはリダイレクトを作成するために好ましい方法ですが、ウェブ開発者がサーバーを制御できない、あるいは設定できない場合があります。このようなでは、ウェブ開発者は <head> 内に <meta> 要素と refresh を設定した http-equiv 属性を持つ HTML ページを構築できます。ページを表示するとブラウザーはこの要素を発見して、示されたページへ移動します。

<head> 
  <meta http-equiv="refresh" content="0; URL=http://www.example.com/" />
</head>

content 属性は、指定した URL へリダイレクトする前にブラウザーが何秒待つべきかを示す値から始まります。アクセシビリティを高めるため、常に 0 を設定しましょう。

当然ながらこの方法は HTML ページ (あるいは同様のリソース) でしか動作せず、画像などのコンテンツでは使用できません。

このリダイレクトはブラウザーの戻るボタンの動作を乱しますので注意してください。このヘッダーを持つページに戻ることはできますが、即座に再び転送されます。

JavaScript リダイレクト

JavaScript のリダイレクトは window.location に値を設定することで作成され、新たなページが読み込まれます。

window.location = "http://www.example.com/";

HTML リダイレクトと同様にすべてのリソースでは動作できず、また JavaScript を実行するクライアントでしか動作しないことは明らかです。一方、例えば特定の条件に一致した場合にのみリダイレクトを行うなど、さまざまな可能性があります。

優先順位

使用可能な URL リダイレクトが 3 種類あり、同時に複数の方法を指定できますが、どのリダイレクトが始めに適用されるのでしょうか? 優先順位は以下のとおりです:

  1. ページが転送されていない、および読み込まれていない状態でも、HTTP リダイレクトが常に最初に動作します。
  2. HTTP リダイレクトが存在しなければ、HTML リダイレクト (<meta>) が動作します。
  3. JavaScript リダイレクトが最後に使用されます。また、クライアント側で JavaScript が有効である場合に限り動作します。

可能であれば常に HTTP リダイレクトを使用して、<meta> は追加しないようにしましょう。誰かが HTTP リダイレクトを変更して HTML リダイレクトを変更し忘れると、リダイレクトが同一ではなくなったり、無限ループになったり、その他の問題が発生したりします。

使用例

リダイレクトの使用例は多数ありますが、どのリダイレクトもパフォーマンスへの影響がありますので、使用は最小限にとどめるべきです。

ドメインの別名

理想的には、ひとつのリソースに対してひとつの場所、そしてひとつの URL が存在します。しかし、リソースに対して別名を持ちたい理由ががあります (複数のドメイン、www 接頭辞がある URL とない URL、覚えやすくて短い URL など)。このような場合はリソースを重複させず、ひとつの正しい (正式な) URL へのリダイレクトを使用すると便利です。

ドメインの別名は、いくつかの理由で実施できます:

  • サイトへの到達方法を広げます。よくある事例は、サイトが www.example.com ドメイン配下に存在しているとき、example.com からページにアクセスすることも可能にしたい場合です。この場合は、example.com のページから www.example.com へのリダイレクトを設定します。また、一般的に使用される同義語や、ドメイン名のタイプミスで頻度が多いものを提供してもよいでしょう。
  • 別のドメインに移動します。例えば会社名が変わった後に古い社名で検索するとき、以前の会社のウェブサイトを使用する人々が新しい社名のもとで今までどおり見つけられるようにしたいでしょう。
  • HTTPS を強制します。HTTP 版のサイトへの要求を HTTPS 版のサイトにリダイレクトします。

ウェブサイトを再構築すると、リソースの URL が変わります。ウェブサイトの内部のリンクは新しい命名体系に合わせるよう更新できますが、外部のリソースで使用している URL は制御できません。外部のリンクは貴重なユーザーを連れてきますので (および SEO のため)、リンクを壊したくはありません。よって、古い URL から新しい URL へのリダイレクトを設定します。

この手段は内部のリンクを機能させることもできますが、内部のリダイレクトは避けるようにするべきです。リダイレクトはパフォーマンスの負担がかなりあります (追加の HTTP 要求を行うため)。内部のリンクを正しくすることでこれを避けられるのであれば、リンクを修正するべきです。

安全でない要求への一時的な応答

安全でない要求はサーバーの状態を変更するものであり、ユーザーがうっかり再実行するべきではありません。一般的に、ユーザーが PUTPOSTDELETE の要求を再送信することは望みません。要求の結果として応答を返すだけである場合は、単に再読み込みボタンを押すことで (おそらく確認メッセージの後に)、要求を再送信します。

この場合、サーバーは正しい情報を持つ 303 (See Other) 応答を返すことができます。一方、再読み込みボタンが押された場合はページを再表示するだけであり、安全でない要求を再実行しません。

長い要求に対する一時的な応答

時には DELETE 要求を後で処理するように予定するなど、一部の要求はサーバー側で長い時間が必要になる場合があります。この場合、応答を 303 (See Other) として操作が実行予定に追加されたことを示すページにリンクし、最終的に進捗を確認したり、キャンセルできるようにしたりするようにします。

一般的なサーバーにおけるリダイレクトの設定

Apache

リダイレクトはサーバーの設定ファイルか、各ディレクトリの .htaccess で設定できます。

mod_alias モジュールに、 (既定で) 302 応答を設定するための Redirect および RedirectMatch ディレクティブがあります。

<VirtualHost *:80>
	ServerName example.com
	Redirect / http://www.example.com
</VirtualHost>

URL http://example.com/http://www.example.com/ にリダイレクトされ、その下のファイルやディレクトリも同様です (http://example.com/index.htmlhttp://www.example.com/index.html にリダイレクトされます)。

RedirectMatch も同じですが、対象の URL の集合を定義するために正規表現を使用します:

RedirectMatch ^/images/(.*)$ http://images.example.com/$1

images/ フォルダー内のすべてのドキュメントが、別のドメインにリダイレクトされます。

一時的なリダイレクトを設定したくない場合は、別の種類のリダイレクトを設定するために追加パラメーター (使用する HTTP 状態コードまたは permanent キーワード) を使用できます。

Redirect permanent / http://www.example.com
Redirect 301 / http://www.example.com

mod_rewrite モジュールも、リダイレクトを作成するために使用できます。こちらはさらに柔軟性がありますが、使い方が若干複雑です。

Nginx

Nginx では、リダイレクトしたいコンテンツ用の server ブロックを作成します。

server {
	listen 80;
	server_name example.com;
	return 301 $scheme://www.example.com$request_uri;
}

フォルダーまたはページのサブセットにのみにリダイレクトを適用するには、rewrite ディレクティブを使用します。

rewrite ^/images/(.*)$ http://images.example.com/$1 redirect;
rewrite ^/images/(.*)$ http://images.example.com/$1 permanent;

IIS

IIS では、<httpRedirect> 要素を使用してリダイレクトを設定します。

リダイレクトループ

連続的なリダイレクトが、すでに通っている経路をたどるとリダイレクトループが発生します。言い換えると終わらないループが存在しており、最終的に見つかるページはありません。

ほとんどの場合はサーバーの問題であり、サーバーが検出できない場合は 500 Internal Server Error を返すでしょう。サーバーの設定を変更した直後にこのようなエラーが発生した場合は、リダイレクトループが発生しているかもしれません。

時々、サーバーがリダイレクトループを検出しないことがあります。それぞれのサーバーでは全貌を把握できない、複数のサーバーにわたるリダイレクトループがあり得ます。。この場合はブラウザーがループを検出して、エラーメッセージを表示するでしょう。Firefox では以下のメッセージを表示します:

このアドレスへの要求に対するサーバの自動転送設定がループしています。

Chrome では以下のように表示されます。

このウェブページにはリダイレクト ループが含まれています

どちらの場合も、ユーザーができることはほとんどありません (キャッシュや Cookie の不一致など、ユーザー側で問題が発生している場合を除きます)。

リダイレクトループはユーザー体験を完全に損ないますので、避けることが重要です。

ドキュメントのタグと貢献者

このページの貢献者: mfuji09, yyss
最終更新者: mfuji09,