Uniform Resource Identifier

Uniform Resource Identifier（ユニフォーム リソース アイデンティファイア、URI）または統一資源識別子（とういつしげんしきべつし）とは、抽象的または物理的なリソースを識別するためのコンパクトな文字列のことである。また、一定の書式によってリソース（資源）を指し示す識別子である。1998年8月に RFC 2396 として規定され、2005年1月に RFC 3986 として改定された。URI はUniform Resource Locator (URL) の考え方を拡張したものである。URIによって示されるリソースは限定されておらず、インターネット上に存在しない対象や抽象的な概念を示す場合もある。

設計

URL と URN 

URI には、以下の2つのサブセットがある。
Uniform Resource Locator (URL)
リソースの「場所」を識別する。ネットワーク内の位置を示してリソースを同定する。
Uniform Resource Name (URN)
リソースの「名前」を識別する。もしネットワーク上にリソースが無くなっても、一意で永続的な識別を行えるようにする。例えば urn:ietf:rfc:2648 というURNは、RFC 2648への参照を示す。

2001年、W3CはRFC 3305内で、上記の考え方を古典的な見解とした。ここで示されたW3Cの新たな考え方により、従来のURLとURNとはすべてURIと呼ばれることになった。URLやURNといった語はW3Cによって非公式な表現とされた。

2012年、WHATWGによってURL Standardの開発が開始された。URL Standardでは、目標の1つとしてRFC 3986 (URI)とRFC 3987 (IRI)を過去のものにすることを掲げている。また、従来のURIやIRIを区別する必要が無いとして、すべてURLの語を用いている。さらに、W3Cでも、このURL Standardのスナップショットをワーキンググループノートとして公開している。

共通構文 
以下のURI共通構文はすべてのスキーム構文で扱うスーパーセットの定義である。なおこの節（下位含む）では2005年1月に発表された RFC 3986 を主に出典とする。

URI = scheme:[//authority]path[?query][#fragment]

URIの長さは RFC 3986 、URL Standard共に255文字までと定められているが、URL Standardでは「有効なIPv4アドレス」が付け加えられている。

と各コンポーネントの解説は次の通り。

 scheme（スキーム）
 URIはこの「スキーム」と呼ばれる識別子から始まり、省略できない。階層的識別子（Hierarchical Identifiers）である:（コロン）はスキームの区切り文字でスキーム名の最後に挿入する。スキーム名は文字で始まり、文字、数字、+（プラス記号）、-（ハイフン）、.（終止符）で構成される文字列となる。大文字と小文字を区別しないが、一貫性を保つために小文字の使用を推奨している。
 authority（権限）
 権限は//（ダブルスラッシュ）の区切り文字から始まる。userinfo（ユーザー情報）やhost（ホスト）の扱いは各スキームよって異なる。URIの考案者であるティム・バーナーズ＝リーは2009年10月12日（現地時間）、ニューヨーク・タイムズにて権限の区切り文字であるダブルスラッシュについて「必要では無い事が判明した」と述べている。
 path（パス）
 URIに権限が含まれている場合、パスに文字が無くても/（スラッシュ）で始める必要があり、この事からパスを省略することはできない。権限が含まれていない場合は//で始めることはできない。さらに相対パスである場合は:から始めることはできない。パスに?（疑問符）、#（番号記号）を含む、あるいは末尾の場合、パスの終わりを示す。階層的（hierarchical）に構成されたデータが含まれ、階層は/で区切る。
 query（クエリ）
 クエリは?の区切り文字から始まり、#また末尾で終える。パスと違い、階層的なデータを含まない。RFC 3986、第3章4節において明確的な構文は示されてない。
 fragment（フラグメント、素片）
 フラグメントは#の区切り文字から始まる。任意な扱いで、プライマリ（一次）リソースを参照し、セカンダリ（二次）リソースへ提供するフラグメント識別子を含む。クエリと同様に明確的な構文は示されてない。一例としてプライマリリソースがHTMLドキュメントの場合、要素のid属性に何かしらの値を指定し、フラグメントにも同様の値を指定することで、ウェブブラウザは表示の際にその要素の位置までスクロールする。ウィキペディアでは「アンカー」と呼ばれる機能が該当する。

 電話番号、電子メールアドレスは RFC 3191 及び RFC 3192 で定義されている構文を利用する。

予約文字とパーセントエンコーディング 

上記で列挙した文字は、URI共通構文で区切りとして予約された文字（Reserved Characters）である為、コンポーネント内で直接使用することはできない。なお[と]（角括弧）はIPv6の区切り文字である。sub-delimsはURIスキームの仕様によって定義されることがある。

パーセントエンコーディング（Percent-Encoding）は上記で列挙した予約文字などをURIで使えるよう、別の形式に変換する。名前のとおり、パーセント記号%とオクテットを16進数で表現した文字を組み合わせた形式で表す。例えばスペース（空白）文字 をパーセントエンコーディングすると%20に変換される。

予約されていない文字（Unreserved Characters）には制約無く、コンポーネント内で自由に使える文字。予約されていない文字は次の通り（RFC 3986 第2章3節）。

 英字 ： AからZ、そしてaからz
 数字 ： 0から9
 一部の記号 ： -、.、_（アンダースコア）、~（チルダ）

なおチルダ~は古いURIの仕様によってしばしば%7eに変換される事がある。しかしてチルダ含め、予約されていない文字の変換は必要無い。

http/httpsスキームの構文例 
http/httpsスキームの構文を使った例：

#共通構文と同じコンポーネントの解説は除く。

userinfo（ユーザー情報、認証情報）はホスト:ポートよりも先に記載する必要がある。開始の区切り文字は無く、@（アットマーク）で区切る事でユーザー情報の終わりを示す。ユーザー情報の形式はuser:passwordである。URIにユーザー情報が付加され、かつその情報が正しければウェブブラウザは認証ダイアログを表示せずプライベートページを表示させることができる。認証情報を平文で示す為、パスワードを含んだ認証情報は非推奨である。これはURL Standardでも同様である。

host（ホスト）はhttp/httpsスキームにおいて必要な権限であり、省略することはできない。port（ポート）はスキームのデフォルトポートであれば省略できる。

クエリはパスに対しての引数であるがその構文は明確的に示されてない。一般的な利用法は、「名前」と「値」の組み合わせ（、またはキーペアなど）で扱われ、構文にするとkey=valueとなり、「名前」と「値」の間は=（イコール）で結ぶ。このペアが複数存在する場合、上記構文例のように&（アンパサンド）で繋げる。クエリはWebサーバ及びクライアント側で処理できる。URL StandardではJavaScript上でクエリ文字列を簡単に扱えるようURLSearchParams()メソッドが実装されている。

フラグメントはクライアントのみ影響する。URIを決定する際、アプリケーションはフラグメントを除外してからサーバーにリクエストを送る。

公式登録のスキーム 

IANAに登録されているスキームで、利用が続いている一部を掲載する。

一般的な非登録のスキーム 

 javascript
 ウェブブラウザやHTMLドキュメントでJavaScriptを実行する手段として用いられている。ドラフト状態であったが2011年3月29日に期限切れを迎えた。

関連項目 
 Extensible Resource Identifier (XRI)
 Internationalized Resource Identifier (IRI)
 短縮URI (CURIE)
 Uniform Resource Locator (URL)
 Uniform Resource Name (URN)
 名前空間
 パーセントエンコーディング

脚注

参考資料 
  - Uniform Resource Identifiers (URI): Generic Syntax (旧)
 TS X 0097:2004 - 統一資源識別子(URI) 共通構文 標準仕様書(TS)
  - Uniform Resource Identifier (URI): Generic Syntax
  - URI Design and Ownership
 URL Standard
 URL Standard 日本語訳
 URL W3C Working Group Note
 URI Schemes -  IANAのURIスキーム登録簿

識別子
Uniform Resource Locator
インターネット標準
2396