URI
目的
Web上に置かれた情報(資源、リソース)に、プログラムから簡単にアクセスできるようにするには?
→資源各々に、プログラムで処理しやすい「名前」をつけよう
URI (Uniform Resource Identifier)
インターネット上のリソースの「名前」(識別子, identifier)
インターネット上のリソースのURIは、すべてインターネット上で一意に定まる。
URL (Uniform Resource Locator) と URN (Uniform Resouce Name) の総称
URN : ドメイン名とは独立にリソースにIDを振る方法
例:
urn:isbn:9784774142043
現代のWebではほとんど使われない(URI = URL と思ってほぼ差し支えない)
現在のインターネットでは、URL(Uniform Resource Locator)とほぼ同義であると考えて良い。
URIはWebで主に使われているが、Webに限った考え方ではない。Web以外の通信でも使うことができるし、パソコンやスマートフォンでアプリケーション内部から別のアプリケーションを起動する際にも用いられることがある。
例
http://www.ietf.org/rfc/rfc2396.txt
http://pubinfo.oka-pu.ac.jp/searchApp/viewSyllabus.php?id=1642
ftp://ftp.is.co.za/rfc/rfc1808.txt
mailto:John.Doe@example.com
tel:+1-816-555-1212
URIの利用例
ブラウザで表示するページの指定
HTML中のリンクの指定(例:
<a href=”http://www.example.com/”>example.com</a>
)スマートフォンのアプリ内でURI
tel:+1-816-555-1212
にアクセスすると、電話アプリで+1-816-555-1212
に電話をかける。
URIの意義
http://example.com/about/index.html
というURIを例にして、URIの意義を述べる。
後述するように、このURIは主に以下の3つの部分からなっている。
URIスキーム:
http
オーソリティ:
example.com
パス:
/about/index.html
この例におけるオーソリティは example.com
というFQDNである。1章で述べた通り、FQDNはDNSによってただ一つのIPアドレスに対応づけられる。そして、IPアドレスは(TCP/IP通信の制約として)インターネット上で一意に定まる。また、URIスキーム+パスで、当該コンピュータ(この例ではexample.com
)上でリソースが一意に定まる。この2点を合わせることにより、URIはインターネット上におけるリソースの一意性を保証しているわけである。
またURIは、リソースにアクセスする手段をコンピュータに容易に解析可能な方法で記述するという側面を持っている。例えばクライアントが上の例で示されたリソースを取得する場合は、オーソリティで示されたサーバに、URIスキームで示されたプロトコルで接続し、パスで示されたリソースを取得すれば良い。つまり、リソースへのアクセスを完全に自動化することができる。ブラウザでリンクをクリックするだけでリンク先のページに遷移することができるのは、まさにこのURIの性質によるものである。
URIの構文
URIはいくつかの構成要素からなっている。詳細な構文はRFC3986に厳密に定められている。
URIスキーム:URIが利用するプロトコルなど。
mailto
やtel
など、以下の構文に従わず、別途構文が定められているURIスキームもある。
オーソリティ(authority):各資源の名前の一意性を保証する単位。
ホスト名:その資源を提供するコンピュータ名。FQDNまたはIPアドレスである場合が多い。
ユーザ情報:URIの指し示すリソースにアクセスするのにユーザ認証が必要となる場合、正当なユーザ名とパスワードをURIに含めることができる。
ポート番号:URIにアクセスするためのTCPポート番号。
URIスキームで指定されたプロトコルのデフォルトポート番号の場合は省略可(例: HTTPなら80番の場合は省略可)
パス:オーソリティ内での資源の識別子。最も簡単な場合、資源(ファイル)への絶対パスになる。
クエリパラメータ:検索サービスに対する検索キーワードの指定など、クライアントからサーバに何らかのパラメータを渡したい場合に用いられる。
URIフラグメント:リソース内部の、さらに細かい部分の指定に用いられる。
例
http://www.ietf.org/rfc/rfc2396.txt
URIスキーム:
http
オーソリティ:
www.ietf.org
パス:
/rfc/rfc2396.txt
foo://bar:baz@example.com:8042/over/there?name=ferret&encoding=utf8#nose
URIスキーム:
foo
オーソリティ:
bar:baz@example.com:8042
ユーザ情報:
bar:baz
(ユーザID:bar
, パスワード:baz
)ホスト名:
example.com
ポート番号:
8042
パス:
/over/there
クエリパラメータ:
name=ferret&encoding=utf8
URIフラグメント:
nose
URI構文に関する補足
URIスキームとそれ以下の部分は
://
で区切られる。ユーザ情報中のユーザIDとパスワードは
:
で区切られる。ユーザ情報とホスト名は
@
で区切られる。ホスト名とポート番号は
:
で区切られる。ユーザ情報、ポート番号は省略可。
パスとクエリパラメータは
?
で区切られる。クエリパラメータについて
一つのパラメータは「パラメータ名=値」という形式
複数のパラメータを並べる場合は
&
で区切る。
URIフラグメントとその前の部分は
#
で区切られる。
URIと文字
URIには、ASCII文字集合の一部の文字(アルファベット、数字、一部の記号)しか使えない。空白記号や日本語の文字などをURIに含めたい場合は、%エンコーディングという方式を用いて、URIに適した文字列に変換(符号化、encode)しなければならない。%エンコーディングの詳細はRFC3986に書かれているが、簡単に言うと「バイトごとに 0x○○ → %○○ と変換」という処理を行う。例を以下に示す。
空白記号(0x40)→
%40
「あ」という文字(UTF-8 では 0xE3 0x81 0x82 の3バイトで表現される)→
%E3%81%82
%エンコーディングの結果から容易に符号化前の文字列を逆変換(復号、decode)できることは明らかであろう。このように、通信路の制限から、通信したいデータを送信側で符号化し、受信側で復号するという事例は、Webに限らずあちこちで見ることができる。
なお、%エンコーディングを使わずに、直接URIの中でUnicode文字集合の文字を使えるように拡張した規格(Internationalized Resource Identifier, IRI)もあるが、まだ普及には至っていない。
よりよいURI
Webでは、リソースを一意に指し示す識別子としてURIが使われ、外部からのリンクを含め、すべてのリソースへのアクセスはURIを使って行われる。ということは、ある情報をWebでリソースとして公開した後、そのリソースのURIを変更してしまうと、そのリソースはWeb上では「行方不明」になってしまうことになる。 つまり、究極的には、リソースに対するURIは未来永劫にわたって不変であることが望ましい。Web開発者は、リソースを公開する前に、そのURIの寿命が可能な限り長くなるようにURIを慎重に設計し、またURIの維持管理をすべきなのである。
どういうときにURIが変わってしまうのか
ありがちな例をいくつか挙げてみよう。
サーバ機のリプレースでWebサーバのホスト名が変わってしまった
http://server1.example.jp/
→http://server2.example.jp/
Webサーバ上で、公開しているファイルの名前を変更した
http://example.jp/foo.html
→http://example.jp/bar.html
Javaで作られていたWebアプリケーションをRubyで再実装した
http://example.jp/servlet/LoginServlet
→http://example.jp/login.rb
よりよいURIを設計するには
実装依存の情報、時間が経てば変化する可能性のある情報を含めないようにする
http://example.jp/
(example.jp
という組織がある限り不変)サーバ管理技術で
server1
,server2
といったサーバ名はURIから隠蔽できる
http://example.jp/foo.html
(ファイル名を変更してもURIを変えないようにできる)http://example.jp/login
(Webアプリケーションの実装言語によらず、ログイン機能があるかぎり不変)http://example.jp/2014/10/16
(2014年10月16日に公開された情報。情報の公開日は時間がたっても不変)http://example.jp/news/latest
(最新のニュース)http://twitter.com/kunishi/status/13211
(ユーザkunishi
の、ID番号13211
のツイート。kunishi
がTwitterに登録していて、ツイートを消したりしない限り不変)
できる限り、URIはリソースをシンプルに表現するように考える
どうしてもURIを変更しなければならないときは
極力、HTTP リダイレクト(古いURIを新しいURIに転送するHTTPの仕組。後述)を使う。
Last updated
Was this helpful?