HTTPエラーページに意味を持たせよう

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ステータスコードのエラーページの作成を扱う:

独自のエラーページの作成

サイトのデザインに合うようにすることができるので、どんなサイトであろうともエラーページを作成することは良い考えである。もし独自のエラーページを設定しなかった場合、訪問者は使用されているウェブサーバーやフレームワークのデフォルトのエラーページを見るだけだろう。

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で探して見ると良い)

  1. HTMLファイルを作成()
  2. Apacheをインストールした場所にあるhtdocsディレクトリに保存
  3. このHTMLファイルを404エラーのページとして提供するようにApacheを設定(注1)
  4. Apacheを再起動(注2)

注1: メインの設定ファイルはhttpd.confまたはapache2.confで、使用しているApacheのバージョンにより異なる。

ErrorDocument 404 /srv/awesome.com/htdocs/404.html

上記のようなメインの設定ディレクトリにエラー文書を置いた場合、そのサーバーのすべてのサイトとバーチャルホストのエラーページになる。バーチャルホストごとにエラーページを別のものにしたい場合は、それぞれのルートディレクトリにエラー文書を置き、ErrorDocumentディレクティブで設定する必要がある。詳しいバーチャルホストの設定方法はApache バーチャルホスト説明書を参照のこと。

注2: 再起動方法

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対策について

本来は404410であるべきページをあえて200 OKにするというケースもある。これはSEO対策のテクニックで、削除したページがインバウンド・リンクを多く獲得している時に使用する。こういった特別なケースの場合はインバウンド・トラフィックをキープし続けるために削除したコンテンツの変わりに特別なエラーページを用意してやると良い。

より詳細な問題への警告

落とし穴

エラーページを作成する際にはまりがちな落とし穴がいくつかある。

エラーページのリソース消費には注意する

リファラや過去のデータから抽出されたキーワードによる検索結果を追加している場合、静的なページを提供するよりもかなり多くのリソースを消費していることに気をつけなくてはならない。リソースの消費を抑えるには、少しの間検索結果をキャッシュすることを考えた方が良い。そうすれば短い間にたくさんのエラーに遭遇したとしても、サーバーのリソース消費は抑えることができる。

HTTPステータスコードは正確に返す

よくある間違いとして、エラーページを作成して、それを200 OKで提供してしまうという間違いがある。検索エンジンがサイトをインデックスする時に、404410として提供されるべきにも拘らず200 OKを返された場合にそのエラーページそのものをインデックスしてしまうという問題が起こることがある。その結果としてより意味のあるコンテンツの代わりにエラーページがリストアップされてしまうことになる。

またエラーページへリダイレクトすることも避けるべきである。要求されたURLのまま正確なステータスコードを返すべきで、URLを変更するべきではない。

変更したURLにはリダイレクトを設定する

理想としてはすべてのURLは恒久的なものであるべきだが、実際は何かしらの理由でURLを変更せざるを得ないことがある。

もし404エラーがページの移動によって起こってしまう場合は、訪問者が意識することなく新しいURLに移動することができるように301 Moved Permanentlyを使って修正する。このステータスコードを使うと検索エンジンが新たなURLを変わりにインデックスしてくれ、検索結果において古いURLを置き換えてくれる(古いURLが検索結果として出てきていたところが丸々置き換わる)。

CMSが自動的に301 Moved Permanentlyによるページの移動をも管理できるようになっていれば理想的だ。

時間経過でのリダイレクトは行わない

Yahoo!の404ページではmeta要素によるリフレッシュで10秒後に訪問者をそのホームページにリダイレクトさせる。404ページに検索フォームを用意しているのにも拘らずだ。つまり検索フォームに単語を入力している時にいきなりホームページへリダイレクトさせられることになる。このような"機能"は避けるべきだ。

まとめ

この記事では訪問者が何かしらの間違いが起きたページにアクセスした時にそれに関連するコンテンツを提示できるように考えられた効果的なエラーページを作成する方法を解説した。こうすることによって訪問者を満足させ、検索結果のページに戻ることなくあなたのサイトでの滞在時間を延ばすことになるだろう。