Web ページの同一性という問題
インターネット上の Web ページは、同一のファイルであっても、異なる URL が付与されてしまうことがあります。
その時に、URL を構成する各要素によって、同じコンテンツでも、異なる URL でアクセスすることができてしまいます。
URLの構成として、説明に使用する用語を次のように定義します。
ここでの説明に使用する URL 構成の用語:
http:// | user:password@ | example.com | :80 | /path | ?name=value | #fragment |
スキーム | 認証情報 | ホスト | ポート番号 | パス | クエリ | フラグメント |
より一般的な URL の構成については、以下のページが参考になります。
Uniform Resource Locator - Wikipedia
http://ja.wikipedia.org/wiki/Uniform_Resource_Locator
RFC 1738 - A Gopher URL Format
http://tools.ietf.org/html/rfc1738
URL
http://www.w3.org/TR/url/
http://ja.wikipedia.org/wiki/Uniform_Resource_Locator
RFC 1738 - A Gopher URL Format
http://tools.ietf.org/html/rfc1738
URL
http://www.w3.org/TR/url/
以下で、その URL を構成する各要素について、詳細に見てみます。
フラグメント(#)
その要因として、まず、フラグメント(#)がつくという点が挙げられます。このフラグメント(#)は、文脈によってハッシュやアンカーなどと呼ばれます。
フラグメント(#)は、一般的には同一ページ内のジャンプ先を主に示しています。そのため、同じページを示す URL であっても、フラグメント(#)のあるURLと、フラグメント(#)の後ろに様々な文字列が付与されたURLといった形に、様々なパターンの URL が生まれます。
従って、URL にフラグメント(#)が付与されていた場合には、同一ページが異なるページであると判断されることを防ぐため、フラグメント(#)以降の文字を削除することで、同一ページのURLを生成します。
但し、それ以外の使われ方をしている場合もあります。例えば、AJAX で実装されているコンテンツの場合、異なる情報を表示するためにフラグメント(#)を使用しています。
AJAX クロール: ウェブマスターおよびデベロッパー向けガイド - ウェブマスター ツール ヘルプ
https://support.google.com/webmasters/answer/174992?hl=ja
https://support.google.com/webmasters/answer/174992?hl=ja
このフラグメント(#) の値は、誰でも URL に付与することができるため、フラグメント(#)を使用することを意図していないページであっても、フラグメント(#)が付与されたURLを渡されたり、ブラウザ側では URL にフラグメント(#)が付与された状態で見える場合があります。
クエリ(?)
URL には、? から始まるクエリと呼ばれる文字列を付与することができます。例えば、URL の ? の後に、ページの生成に使用する様々なパラメータを付与することができます。
例)
?a=1&b=2
そのパラメータの値をサーバ側のプログラムや、場合によってはクライアント(ブラウザ)側のプログラムが見て、動的にコンテンツを生成します。
また、場合によってはトラッキングのためのパラメータを付与することもあります。
そして、これ以外の使われ方をされている場合もあるかもしれません。
このクエリの値は、誰でも URL に付与することができるため、クエリを使用することを意図していないページであっても、クエリが付与された URL が渡されたり、ブラウザ側では、URL にクエリが付与された状態で見える場合があります。
従って、Webページの URL をブラウザ側で動的に取得しようとした場合に、同一のコンテンツであっても、上記の理由から異なる URL を取得する場合があります。
ホスト
ホストが異なる URL であっても、同一のコンテンツを示していることがあります。例えば、通常のドメインの URL と、そのドメインのサブドメインに www が付与された URL で、同じコンテンツが配信されている場合があります。
また、ホストの部分は IP アドレスの形式で渡される場合もあります。
また、Blogger という Google が提供するブログサービスでは、ブログにアクセスする国によって、異なるドメインの URL へとリダイレクトされます。
ブログが国別の URL にリダイレクトされる理由(ccTLD) - Blogger ヘルプ
https://support.google.com/blogger/answer/2402711?hl=ja
https://support.google.com/blogger/answer/2402711?hl=ja
パス
パスが異なったページであっても、異なるコンテンツではないかもしれません。また、index.html などといったファイルは、そのファイル名部分を省略してもアクセスできるようになっている場合が多く、ファイル名のある URL と、ファイル名の無い URL で複数のパターンの URL が生まれる原因になります。
ポート番号
URL には、アクセスする Web サーバのポート番号を含めることができます。
http といったプロトコルの標準のポート番号であれば、そのポート番号は省略して表記されますが、あえて明記された URL が渡されることがあるかもしれません。
スキーム
一般的な Web ページには、http を使用してアクセスしますが、最近は個人情報が含まれない web ページであっても、 https で接続することも増えてきました。Web サイトによっては、http と https で、同一のコンテンツを配信するようになっている可能性もあります。
認証情報
URL には、認証に使用するユーザ名とログインパスワードを埋め込むことができます。
JavaScript:location.hrefの注意点 - URLのドメイン前にベーシック認証が埋め込める、そして脆弱性 - Dr.ウーパのコンピュータ備忘録
http://upa-pc.blogspot.jp/2015/02/javascript-location-href-url-basic-trouble.html
http://upa-pc.blogspot.jp/2015/02/javascript-location-href-url-basic-trouble.html
この認証に使用するユーザ名とパスワードは、ユーザ名とパスワードによる認証が行われていない Web ページの URL に対しても埋め込むことができます。
そのため、url を見て web ページの同一性を判断する場合には、この認証情報は削除してから比較しなければなりません。
その他
あと考えられるのは、日本語ドメインのような国際化ドメイン名と、Punycode の対応付けを行わずに、別々の URL であると認識するケースでしょうか。
Chrome:日本語ドメインをアドレスバーからコピペすると別の文字列に変わる!それはPunycode(ピュニコード)です - Dr.ウーパのコンピュータ備忘録
http://upa-pc.blogspot.jp/2015/02/chrome-punycode.html
http://upa-pc.blogspot.jp/2015/02/chrome-punycode.html
異なる URL であっても、同一のコンテンツである場合には、それが同一のコンテンツなのか異なるコンテンツなのかを、どうやって判断したらよいのでしょうか?
正規化されたURLという解決手段
この問題の一つの解決策として、正規化されたURL(canonical)を使用する方法があります。javascript:WebページのURLをlocationからではなく、HTML文書中のcanonicalから取得する理由
http://upa-pc.blogspot.com/2015/03/javascript-why-should-get-the-url-from-canonical.html
ただし、上記のページに記載したように、canonical として記載された URL を使って、本当にそのページを同一コンテンツとして見なしてよいかは、考える必要があります。
また、正規化された URL が指定されていない web ページもあるため、注意が必要です。
まとめ
このように、同じコンテンツであっても、異なるURLのバリエーションは無数にあります。そして、URL からコンテンツの同一性を考えることには限界があります。
そこで、正規化された URL によって、コンテンツの同一性を判断する方法があります。
ただし、正規化された URL を使う上で、いくつかの注意する必要のあることがあります。
コメントを投稿 (ここをクリックしてコメント投稿フォームを表示)
コメント投稿機能について