HTTPリダイレクト4種類の違いとは?
HTTPではリダイレクトするときに300番台のステータスコードを使用する。具体的に言うとリダイレクトを表すステータスコードには301/302/303/307の4種類があって、用途によって使い分けられるようになっている。
が、モバイルの世界では4種類のステータスコードを自由気ままに使えるわけじゃない。実機での調査結果を元に、ステータスコードの使い方をまとめてみた。
関連記事:
リダイレクトの種類
そもそもリダイレクトに種類なんてあるのか!?・・・と思ってしまうけど、HTTP仕様書を見ると次のように用途ごとにステータスコードが割り当てられている。
ステータスコード | 説明 |
---|---|
301 (Moved Permanently) | URLが新しいURLへ永久的に変更されたことを表す。 古いURLを保持しているクライアントは、以後新しいURLのみを使用する。サイトリニューアルでURLが変更になった場合とか、本来アクセスされるURLとは異なるURLへのアクセスを制御させたい時とかに使う。 |
302 (Found) | 一時的に別のURLへ遷移させたい時に使用する。 リダイレクト先は一時的なURLのため、古いURLを保持しているクライアントはこの後も古いURLを保持し続ける。 たとえばサーバーエラーが発生したときにエラーページへリダイレクトする場合とかに使う。 最も広く使われるリダイレクトのステータスコード。 |
303 (See Other) | 新しいURLにGETメソッドでアクセスすることが決められたリダイレクト。フォームからPOSTした後にリダイレクトしてTOPページへ戻す、というような遷移で使う。 HTTP/1.1から導入された。 |
307 (Temporary Redirect) | 一時的に別のURLへ遷移させたい時に使用する。302とよく似ているけど、リダイレクト前と同一メソッドでリダイレクト先へもアクセスを行うところが異なる。 用途があまり思い浮かばないけど、たとえば主系・幅系と2系統で展開しているサイトで、サーバーにトラブルが発生したら、もう片方にリダイレクトして処理を続行させる場合とか。 HTTP/1.1から導入された。 |
このように全部で4種類のステータスコードが用意されている。
4種類のステータスコード、モバイルで使える?
会社にあるフィーチャーフォン7機種、スマートフォン2機種、あと参考までにPCブラウザ1つの動作を調べてみた。以下の表はブラウザがリダイレクトステータスコードを受け取った時に、GETでリダイレクトするのか、POSTでリダイレクトするのか、それともリダイレクトできないのか、という動作結果をまとめたものだ。
ステータス コード | GET 直後の 301 | GET 直後の 302 | GET 直後の 303 | GET 直後の 307 | POST 直後の 301 | POST 直後の 302 | POST 直後の 303 | POST 直後の 307 |
---|---|---|---|---|---|---|---|---|
docomo N-06A | GET (※1) | GET | GET | GET | GET (※1) | GET | GET | POST (※2) |
docomo N905i | GET (※1) | GET | × (※3) | × (※3) | GET (※1) | GET | × (※3) | × (※3) |
docomo N505iS | GET (※1) | GET | × (※3) | × (※3) | GET (※1) | GET | × (※3) | × (※3) |
au X-RAY | GET | GET | GET | GET | GET | GET | GET | POST |
au W61K | GET | GET | GET | GET | GET | GET | GET | POST |
Softbank 945SH | GET | GET | GET | GET | GET | GET | GET | POST |
SoftBank 920P | GET | GET | GET | GET | GET | GET | GET | POST |
iPhone | GET | GET | GET | GET | GET | GET | GET | POST |
Xperia arc | GET | GET | GET | GET | POST | GET | GET | POST (※2) |
Firefox 5 | GET | GET | GET | GET | GET | GET | GET | POST (※2) |
※1 「サイトが移動しました(301)」というダイアログが表示され、「OK」を選択するとリダイレクト先へ遷移する。
※2 「新しいサイトへデータを再送信しますがよろしいですか?」などの選択ダイアログが表示され、「YES」を選択するとリダイレクト先へ遷移する。「NO」を選択するとリダイレクトしない。
※3 「無効なデータを受信しました」というダイアログが表示され、先へ進めない。
ごちゃごちゃした表になっているけど、ステータスコード別に結果を簡単にまとめるとこうだ。
- 302は全機種で対応
- 301はdocomoだけ勝手にダイアログが表示されてしまう(リダイレクト先へ進める)
- 303/307はdocomoのiモードブラウザ1.0機種だけ非対応(リダイレクト先へ進めない)
全機種対応を考えるなら302しか選択肢がない。301はdocomoで確認ダイアログが表示されてしまう。リダイレクト先には進めるけどちょっと使いにくい。N905iはHTTP/1.1でWebサーバーへリクエストを送信するけど、303/307には対応していないみたい。HTTP1.1対応と言っておきながら、これはどういうことなんだろう??
302だけを使うのもマズイ!
それなら、リダイレクト時のステータスコードは302だけを使えばいいや・・・と思ってしまう。ところが今度はクローラーの動作に影響を与えてしまう。
Yahoo!のインデックス化に関して、次のような記述がある。
リダイレクトの設定とインデックスに登録されるURL
あるウェブページにリダイレクトが設定されている場合、クローラーは、次のステータスコードをもとに、リダイレクト先のURLをインデックスに登録するか、リダイレクト元のウェブページをインデックスに登録するかを判定します。
- 301リダイレクト:永久的なリダイレクト
- 302リダイレクト:一時的なリダイレクト
ステータスコード302は一時的なリダイレクトだから、リダイレクト先のページはインデックス化せずに、リダイレクト元のページをインデックス化してしまう。WebサイトのTOPページにアクセスしたときに本来のTOPページへリダイレクトを行うことがあるけど、ここで302リダイレクトを使うとWebサイトのインデックス化が正しく行われない可能性がある。
本来は301を使うべき時に302を使おうとしたから、これは致し方ない。あと、Googleは301/302の区別をあまりしないようだ。
まとめ
結局、モバイルの事情を踏まえると、リダイレクトのステータスコードは次のように使い分けるのがよい。
ステータスコード | 用途 |
---|---|
301 | リニューアルなどによるURLの変更や、ドメインTOPから本来のページへのリダイレクトなど、永久的なURL変更を示すリダイレクトに使う。ただし、本来の用途と異なるけどdocomo iモードブラウザ1.0だけは301を使用せず、302を使用する。 |
302 | 一時的なURLの変更を示すリダイレクト。ほとんどこれでOK。 |
303 | docomo iモードブラウザ1.0が非対応なので使用しない |
307 | 同上 |
ステータスコード301に該当するリダイレクトは、Apacheで設定することが多いけど、docomoだけ302を使いたいので設定には一工夫必要。次のようにmod_rewriteを使えば、User-Agent毎にリダイレクト時のステータスコードを分けることができる。
BrowserMatch ^DoCoMo/ docomo=1
RewriteEngine On
RewriteCond %{ENV:docomo} 1
RewriteRule ^/$ /blog/foo/ [R=302]
RewriteRule ^/$ /blog/foo/ [R=301]
ステータスコード302は、ApacheならRedirectTempディレクティブで実現できる。あと、アプリケーション側から302を送信するのは簡単。たとえば、JavaのHttpServletResponse#sendRedirectメソッドやPHPのheader関数でリダイレクトを行うとステータスコードが302になるから、普通にリダイレクトすればOK。
最後に、ステータスコード303/307は実際に使用されているケースも少なく、あまり考慮する必要はないだろう。
(参考)
- iモード対応コンテンツ作成時の仕様(www.docomo.co.jp)
- HTTP Status Code (www.studyinghttp.net)
- Apache Module mod_rewrite (httpd.apache.org)
- PHP header – Manual(php.net)
関連記事: