Translation of: Adding meaning to your HTTP error pages! by Stuart Colville
This article is licensed under a Creative Commons Attribution, Non Commercial - Share Alike 2.5 license
はじめに
ウェブ上で何かを検索しようとすると、既に存在しないページしか検索結果になく、それらへのリンクをクリックすることはよくあるだろう。その開いたページにデフォルトのエラー・メッセージの他に何も情報が載っていなかった場合、多くの人々は戻るボタンを押し次の検索結果を開こうとするだろう。
サイト製作者である我々はもっと訪問者に意味のあるエラーページを作成することができる。そうすればたとえエラーページであっても訪問者をサイトに留まらせ、彼らが探しているものに関連性のあるコンテンツを提供できるかもしれない。この記事ではどうやってそのようなエラーページを作成するかを説明する。
この記事の目次は以下のようになっている:
一般的なHTTPエラーコード
この記事では以下のHTTPステータスコードのエラーページの作成を扱う:
- 404: ウェブサーバーがページを見つけることができなかった場合、
404 NOT FOUND
というステータスがレスポンスヘッダで返される。このステータスコードに対しては多くのウェブサーバーがデフォルトで限られた情報しか提供してくれないページを表示するようになっている。そのページで使われる言葉はほとんど無益なものであったり、むやみに技術的なものであったりする。 - 410:
410 GONE
というステータスは、故意に削除したということを伝えること以外は404と似ている。例えば、法律上の理由でニュース記事を削除した場合などにはこのステータスコードを使用する。 - 500:
500 INTERNAL SERVER ERROR
というステータスはサーバーに重大な問題が発生した時に使用される。500エラーの一般的な原因はウェブサーバーの設定ミスや、サーバーサイドのコードにおいてエラーが起こった場合である。このページは常に静的に提供されるべきである。なぜならばサーバーサイドのコードがきちんと実行されることが保証できないからである。
独自のエラーページの作成
サイトのデザインに合うようにすることができるので、どんなサイトであろうともエラーページを作成することは良い考えである。もし独自のエラーページを設定しなかった場合、訪問者は使用されているウェブサーバーやフレームワークのデフォルトのエラーページを見るだけだろう。
Apacheのデフォルトのエラーページを変更する理由として他に、Internet Explorerが512バイト以下のエラーページの場合、ブラウザに内包されたエラーページを表示することが挙げられる。すべてのApacheのデフォルトのエラーページはそのサイズを下回っている。
独自のエラーページを使用するために必要なことは、対応したいエラーにたいするHTML文書を作成し、ウェブサーバーやフレームワークをデフォルトの代わりにそれらを使用するように設定するだけだ。
訪問者に何が間違っていたのかを理解させるために、まず最初にエラーページでは何が起こったのかをはっきりとさせることが必要になる。専門用語を避けることによって、訪問者が戻るボタンを押そうと考えないようにする。
デフォルトのApacheのエラードキュメントはこのようになっている:
Not Found The requested URL /blah was not found on this server.
我々開発者ならばURLがどこに書いてあるかすぐにわかるが、あなたのおばあちゃんはどうだろう? サイトの訪問者、ギークであるか"普通"の人々であるかを問わず、に合わせてエラーページの言葉は考えるべきである。
より人間的な例として、Googleのエラーページが挙げられる:
The page - www.google.com/dkjfhsd - does not exist. Suggestions: * Check the spelling of the address you typed * If you are still having problems, please visit the Help Center
Apacheでの設定を例として解説するが、もっと美しくデザインすることを忘れないように(もしセンスが無いという場合にはFlickrで探して見ると良い)
- HTMLファイルを作成(例)
- Apacheをインストールした場所にある
htdocs
ディレクトリに保存 - このHTMLファイルを
404
エラーのページとして提供するようにApacheを設定(注1) - Apacheを再起動(注2)
注1: メインの設定ファイルはhttpd.confまたはapache2.confで、使用しているApacheのバージョンにより異なる。
ErrorDocument 404 /srv/awesome.com/htdocs/404.html
上記のようなメインの設定ディレクトリにエラー文書を置いた場合、そのサーバーのすべてのサイトとバーチャルホストのエラーページになる。バーチャルホストごとにエラーページを別のものにしたい場合は、それぞれのルートディレクトリにエラー文書を置き、ErrorDocument
ディレクティブで設定する必要がある。詳しいバーチャルホストの設定方法はApache バーチャルホスト説明書を参照のこと。
注2: 再起動方法
- Linux:
sudo /etc/init.d/apache2 restart
- Mac OS X:
sudo apachectl restart
ApacheでErrorDocument
ディレクティブを設定する際には注意点がいくつかある。もしフルURLをエラーページとしてしてした場合、Apacheは元々のエラーページのステータスコードの変わりにリダイレクトのステータスコードを返してしまう。エラーページを正確なステータスコードで提供することはかなり重要である。そうしないと検索エンジンのボットを混乱させてしまうだろう。
より良いエラーページの作成
すべてのエラーコードに対して上記例を実践したなら、デフォルトのそれよりも幾分見栄えが良く、訪問者がどんなエラーが起こったのかを理解しやすい独自のエラーページができたことだろう。さらにエラーページを上質なものにするにはどうしたらよいのだろうか?
まず訪問者に効果的なエラーページを作成してみよう。訪問者が何かしらの情報を求めて自分のサイトを訪れたものの404エラーに遭遇した場合、どうすれば彼らをサイトにとどまらせることが出来るだろうか?
検索エンジンのリファラ
ブラウザにより送信されるヘッダであるリファラは訪問者が直前に閲覧していたURLを教えてくれる。ブラウザが送信する他のヘッダと同じようにそれを信頼することはできないが、それでも訪問者がどこから来たのかを推定するのに有用なものである。
以下はGoogleからのリファラよりキーワードを抽出するサンプルである。Googleの検索結果URLはこのようなものである:
http://www.google.co.uk/search?hl=en&q=barista+champion&btnG=Google+Search&meta=
Pythonのurlparseモジュール等の適当なサーバーサイドのプログラミングによりクエリ文字列から適切な部分を切り出すことができる:
>>> import urlparse >>> url = "http://www.google.co.uk/search?hl=en&q=barista+champion&btnG= Google+Search&meta=" >>> url_parts = urlparse.urlparse(url) >>> url_parts ('http', 'www.google.co.uk', '/search', '', 'hl=en&q=barista+champion&btnG=Google+Search&meta=', '')
Python 2.5ではparse_qsはcgiモジュールにある:
>>> from cgi import parse_qs >>> query_parts = parse_qs(url_parts[5]) >>> query_parts {'q': ['barista champion'], 'btnG': ['Google Search'], 'hl': ['en']} >>> terms = query_parts.get('q', None) and query_parts['q'][0].split() >>> terms ['barista', 'champion']
Python 2.6ではparse_qsはurlparseモジュールにある:
>>> query_parts = urlparse.parse_qs(url_parts[4]) >>> query_parts {'q': ['barista champion'], 'btnG': ['Google Search'], 'hl': ['en']} >>> terms = query_parts.get('q', None) and query_parts['q'][0].split() >>> terms ['barista', 'champion']
Python 3.0ではurlparseモジュールはurllib.parseに名前が変更された。Python 3に移行する場合は2to3.pyというスクリプトで更新することができる。
もしユーザーが検索エンジンの検索結果ページから訪問した場合、リファラを見ることによってどのような検索語で検索したかを知ることができる。その検索語を使って自身のサイトを検索してやり、その中から適切なコンテンツを提供することができるだろう。
セキュリティについて
リファラヘッダは容易に偽装ができるので、外部のソースを利用する場合と同じように、リファラとして送られてきたデータの取り扱いには気をつけなければならない。リファラに基づいて何かしらをページに表示する場合、クロスサイトスクリプティングを回避するために確実にエスケープされていることを確認しなければならない。もしリファラのデータからデータベースにクエリを投げる場合は、SQLインジェクションが発生しないようにきちんとフィルタすることが重要である。
訪問者を逃がさないために
検索エンジンの検索結果から訪れたのではない場合、訪問者が何を求めて訪問したのかを知るのは難しい。しかし、訪問者に興味を持たせるアプローチは他にいくつもあるので心配しないで欲しい。
ひとつはもっとも人気のあるコンテンツを提供してしまうことだ。例えばショッピングサイトを運営しているのならば、売り上げトップ10の商品へのリンクを提供してしまえば良い。
他には、リファラのURLからキーワードを抽出するように、閲覧しようとしたURLからキーワードを抽出して検索を行う方法もある。このアプローチは以下のような簡潔なURLでサイトが構成されている時にのみ効果を発揮するだろう:
http://caffeineftw.com/news/2009-world-barista-championships
この例ではURLの最後のパーツをハイフンで切り分けることによって適当な検索語を抽出することができる。"and"や"to"などのstop wordsを削除しても良いが、サイト内検索側でstop wordsを適切に処理できるのなら必要ない。
以下はPythonで抽出する簡単な例である:
>>> url = 'http://caffeineftw.com/news/2009-world-barista-championships' >>> [ item for item in url.split('/') if item !="" ][-1].split('-') ['2009', 'world', 'barista', 'championships']
以下のようなキーワードが抽出される:
2009 world barista championships
404エラーページにこれらのキーワードにマッチするページへのリンクを提供すれば、訪問者がそのサイトのほかのコンテンツにアクセスしてくれる可能性は高くなるだろう。
コンテンツの削除の扱い
最初に触れたように、サイトからコンテンツを削除する必要に迫られることもあるだろう。その場合は410 GONE
というステータスコードを返すべきだ。
理想を言うのならば、CMSではコンテンツを削除するのではなく、訪問者からアクセスできないようにするのみというのが望ましい。そうであるならば、その削除したコンテンツのデータを利用して、関連性のあるコンテンツをリストアップし、410エラーページで提供することができるだろう。
例えば、著名人の結婚についての記事を書いたが、法律上の問題があってその記事を削除せざるを得なかったとしよう。その記事のURLは410 GONE
エラーページにするが、そのURLにはどんな内容の記事があったかは取得できるので、そのタグやその他メタデータを利用して関連性のあるコンテンツを提供することができるだろう。
SEO対策について
本来は404
や410
であるべきページをあえて200 OK
にするというケースもある。これはSEO対策のテクニックで、削除したページがインバウンド・リンクを多く獲得している時に使用する。こういった特別なケースの場合はインバウンド・トラフィックをキープし続けるために削除したコンテンツの変わりに特別なエラーページを用意してやると良い。
より詳細な問題への警告
落とし穴
エラーページを作成する際にはまりがちな落とし穴がいくつかある。
エラーページのリソース消費には注意する
リファラや過去のデータから抽出されたキーワードによる検索結果を追加している場合、静的なページを提供するよりもかなり多くのリソースを消費していることに気をつけなくてはならない。リソースの消費を抑えるには、少しの間検索結果をキャッシュすることを考えた方が良い。そうすれば短い間にたくさんのエラーに遭遇したとしても、サーバーのリソース消費は抑えることができる。
HTTPステータスコードは正確に返す
よくある間違いとして、エラーページを作成して、それを200 OK
で提供してしまうという間違いがある。検索エンジンがサイトをインデックスする時に、404
や410
として提供されるべきにも関わらず200 OK
を返された場合にそのエラーページそのものをインデックスしてしまうという問題が起こることがある。その結果としてより意味のあるコンテンツの代わりにエラーページがリストアップされてしまうことになる。
またエラーページへリダイレクトすることも避けるべきである。要求されたURLのまま正確なステータスコードを返すべきで、URLを変更するべきではない。
変更したURLにはリダイレクトを設定する
理想としてはすべてのURLは恒久的なものであるべきだが、実際は何かしらの理由でURLを変更せざるを得ないことがある。
もし404
エラーがページの移動によって起こってしまう場合は、訪問者が意識することなく新しいURLに移動することができるように301 Moved Permanently
を使って修正する。このステータスコードを使うと検索エンジンが新たなURLを変わりにインデックスしてくれ、検索結果において古いURLを置き換えてくれる(古いURLが検索結果として出てきていたところが丸々置き換わる)。
CMSが自動的に301 Moved Permanently
によるページの移動をも管理できるようになっていれば理想的だ。
時間経過でのリダイレクトは行わない
Yahoo!の404ページではmeta要素によるリフレッシュで10秒後に訪問者をそのホームページにリダイレクトさせる。404ページに検索フォームを用意しているのにも関わらずだ。つまり検索フォームに単語を入力している時にいきなりホームページへリダイレクトさせられることになる。このような"機能"は避けるべきだ。
まとめ
この記事では訪問者が何かしらの間違いが起きたページにアクセスした時にそれに関連するコンテンツを提示できるように考えられた効果的なエラーページを作成する方法を解説した。こうすることによって訪問者を満足させ、検索結果のページに戻ることなくあなたのサイトでの滞在時間を延ばすことになるだろう。