URL 正規化
hatebuize 作るときに google と yahoo で出てくる URL が違うことに気づいてムキーってなって手動で yahoo の URL を google っぽくしてたんだけどそういえば direct_bookmark.js ( http://unsigned.g.hatena.ne.jp/Trapezoid/20080411/1207842257 ) でなんか URL 正規化とかいう関数あったなと思い出してみてみたら pathtraq の URL 正規化 API ( http://pathtraq.com/developer/#help_normalize_url ) 使ってたのでそれで URL 正規化ってなんだろうと思って調べてみた。
最初はサイト立ち上げる際に RFC ( http://www.ietf.org/rfc/rfc1738.txt ) に沿った形にするってことかと思ったんだけど全然違くて異なる複数の URL が同一のページを返す際にどれかひとつに統一しようってことらしい。ただまだ日本だと SEO とか言ってる人くらいにしか馴染みがないみたいなんだけど開発者でも後々のこと考えたりとか閲覧者の利便を考慮したりとか REST とか睨んだりするとこういう知識は必要だと思う。
あとなんか google が index 作るための前処理としてやりはじめたみたいなことが言われてるんだけどそうなの ? それと google の中の人 ( http://www.mattcutts.com/blog/seo-advice-url-canonicalization/ ) は URL canonicalization て言ってるみたいだけど URL normalization とどう違うのか日本人的にはわかりづらい。一応調べてみたけど URL canonicalization のが一般的みたい ( http://native-checker.com/ での調査結果 ) 。 normalize が「 ( 扱いやすい形への ) 一般化」という意味が強いのに比べて canonicalize は「 ( 複数候補の中からの ) 正当な権威付け」という意味合いなのかな ? おしえて言語関係のエロいひと !!
で、意味はまぁわかったんだけど技術としてどうやってるのかってのがさっぱりわかんなかったのでさらに調べてみた。したっけ http://en.wikipedia.org/wiki/URL_normalization が引っかかっていい感じにまとまってたので fmfm 的。ちょっと自分用に以下に訳しとく。
- スキームとホスト名は小文字にしとけ
- URL のスキームとホスト名の部分は大文字小文字で別のものとして扱われる。大体の正規化処理ではこいつらを小文字にするみたい。
- Example: HTTP://www.Example.com/ → http://www.example.com/
- 最後に '/' をつけとけ
- 後続のスラッシュがディレクトリを示している + スラッシュまでが URL に含まれるべき ( 訳注: URL を定義した RFC 1738 では後続になにもなければスラッシュをつけなくてもいいとしているけど、ディレクトリを示す印としてつけるべきという意味なんじゃないかなと思う ) 。
- Example: http://www.example.com → http://www.example.com/
- ディレクトリの索引ページは削っとけ
- デフォルトで表示される索引ページ部分 ( 訳注: 原文は directory indexes 。 URL でディレクトリが指定されている際にデフォルトで表示するページの指定のことで Apache の設定項目名が DirectoryIndex なのでそのまま普及してる ? ) はほとんどの場合 URL に必要ない。
- Examples1: http://www.example.com/default.asp → http://www.example.com/
- Examples2: http://www.example.com/a/index.html → http://www.example.com/a/
- 完全な URL ( 訳注: ファイル名指定まである URL のことかな ) は小文字にしとけ
- 大文字小文字を区別しないファイルシステムの上で動いてるウェブサーバでは URL も大文字小文字を区別しないことがある。そういったウェブサーバが返す URL は曖昧さを避けるために小文字に変換することができる。
- Example: http://www.example.com/BAR.html → http://www.example.com/bar.html
- エスケープシーケンスは大文字にしとけ
- パーセントエンコーディングされている 3 文字は大文字小文字を区別しないので大文字にすべき ( 訳注: RFC 3986 にまったく同じことが書かれている ) 。
- Example: http://www.example.com/a%c2%b1b → http://www.example.com/a%C2%B1b
- フラグメントは削っとけ
- フラグメント ( 訳注: 文書中の特定の場所を id 属性で参照する ) 部分は普通削られる。
- Example: http://www.example.com/bar.html#section1 → http://www.example.com/bar.html
- デフォルトのポートは削っとけ
- デフォルトポート ( http の 80 番 ) は URL から削る ( もしくは付加する ) ことができる。
- Example: http://www.example.com:80/bar.html → http://www.example.com/bar.html
- ドットのみの部分は削っとけ
- ".." と "." は RFC 3986 に書かれているアルゴリズム ( か似たようなモン ) に従って普通 URL から削られる。
- Example: http://www.example.com/../a/b/../c/./d.html → http://www.example.com/a/c/d.html
- 一番最初のドメインラベルとしての "www" は削っとけ
- あるウェブサイトが以下のように 2 つのインターネットドメインで運営されている場合がある。ひとつは最下位ラベルが "www" のもの。もう一つは前者の名前の最下位ラベルを削ったもの。たとえば http://example.com/ と http://www.example.com/ は同じサイトへアクセスするかもしれない。たくさんのサイトは "www" なしのアドレスにリダイレクトする ( 逆もある ) がそうでないものも少数だが存在する。正規化処理では "www" なしと同等のサイトがあるかどうかを確かめて全ての URL を "www" なしに正規化するという追加処理を実行することができる。
- Example: http://www.example.com/ → http://example.com/
- 動的なページは変数をソートしとけ
- 動的なウェブページは URL に 1 つ以上の変数をもっている。正規化処理ではそれらのデータとともに 1 回すべての変数を取り除き、辞書順に ( 変数の名前で ) それらをソート、 URL を再構成することが可能だ。
- Example: http://www.example.com/display?lang=en&article=fred → http://www.example.com/display?article=fred&lang=en
- クエリの中のテケトーな変数は削っとけ
- 動的なページはある変数がクエリの中にあることをを要求するかもしれない。つまり要求されていない変数はすべて削られるべき。
- Example: http://www.example.com/display?id=123&fakefoo=fakebar → http://www.example.com/display?id=123
- クエリの中のデフォルト変数は削っとけ
- クエリの中でデフォルト値に指定されている変数はあってもなくても同じように動作するだろう。そういった変数がクエリにある場合削られるべき。
- Example: http://www.example.com/display?id=&sort=ascending → http://www.example.com/display
- クエリがないなら "?" を削っとけ
- クエリが空のとき "?" は必要ない。
- Example: http://www.example.com/display? → http://www.example.com/display
3, 4, 9, 11, 12 はサイト固有の情報な気がするのでちゃんと正規化をするつもりなら裏にデータベースを抱えてないとダメだね。でもこういう情報は閉鎖的にため込むより wedata とかで共有できるようにすると面白いかも。