URI完全ガイド:構成要素・URL/URNの違い・正規化と実務上の注意(RFC3986準拠)
URIとは
URI(Uniform Resource Identifier)は、インターネット上の資源(リソース)を一意に識別するための文字列の仕組みです。単に「住所」のようにリソースを指し示す役割を持ちます。Webブラウザで使う「http://example.com/index.html」や「mailto:info@example.com」、またファイルやデータを直接記述するdata URIなど、さまざまな形式がURIとして扱われます。
歴史と標準化
-
初期の概念は「URL(Uniform Resource Locator)」として導入され、RFC 1738(1994年)が代表的です。
-
その後、リソースを「識別」するというより一般的な概念を表すために「URI」という上位概念が定められ、RFC 2396(1998年)により汎用構文が提示されました。
-
現在の事実上の標準は RFC 3986(2005年)で、URIの汎用構文、正規化や参照(相対URIの解決)などを定義しています。
-
URN(Uniform Resource Name)の構文については RFC 2141(1997)から RFC 8141(2017年)へと更新されており、国際化を考慮したIRI(Internationalized Resource Identifier)は RFC 3987(2005年)で定義されています。
URIの構成要素(汎用構文)
RFC 3986 に従うと、典型的なURIは次のような構成要素を持ちます(角括弧は省略)。
-
scheme:プロトコル名やスキーム(例:http, https, ftp, mailto, data)。末尾にコロンが付く(例:http:)。スキーム名は大文字・小文字を区別しない。
-
authority:認証情報userinfo(任意)、ホスト名、ポート番号を含む部分(例:user:pass@example.com:8080)。"//"で始まることが多い。
-
path:リソースの位置を示すパス(例:/docs/index.html)。サーバの設定により大文字小文字の扱いが異なる点に注意。
-
query:クエリ文字列(?から始まる)。サーバやアプリケーションでパラメータとして解釈される。
-
fragment:フラグメント(#以降)。URI参照のクライアント側の部分(ブラウザ内の文書内位置など)で、サーバへは送信されない。
URI・URL・URN の違い
しばしば混同されますが、簡潔にまとめると次の通りです。
-
URI:リソースを一意に識別する総称(umbrella term)。
-
URL(Locator):リソースの位置(アクセス方法)を示すURIの一種。例:Web上のファイルにアクセスするためのhttp/httpsなど。
-
URN(Name):恒久的な名前(識別子)を示すURIの一種で、必ずしも位置を表さない(例:urn:isbn:0451450523)。
RFC 3986 では「URI」が包括的な用語として扱われ、URL/URNは用途や意味合いで区別されます。実務では「URL」という語が一般的に使われ続けていますが、技術文書や標準では「URI」を使うのが正しい場面が多いです。
エンコーディングと国際化(IRI)
URI は基本的に英数字と一部の記号のみを安全に使えるため、それ以外の文字(日本語など)はエンコードが必要です。これを「パーセントエンコーディング(%NN)」と呼びます(RFC 3986 セクション2.1)。
国際化された文字(非ASCII)を扱うために IRI(RFC 3987)が導入されており、人間に見やすい表記を可能にします。ただし実際の通信やプロトコル処理では多くの場合 IRI を UTF-8 に正規化し、必要に応じてパーセントエンコードしたり、ドメイン名は Punycode(IDN: 国際化ドメイン名)へ変換したりします。
相対URIと基準(base)
HTMLやXMLなどでは相対URIがよく使われます。相対URIは基準となる「基底URI(base URI)」に対して解決(正規化)されて絶対URIになります。RFC 3986 の Section 5 が相対参照の解決方法を定めています。HTMLでは <base href="..."> 要素が基底URIを指定するために使えます。
正規化・正準化(Normalization)
同じ資源を指す複数のURI表記が存在するとき、比較やキャッシュ、セキュリティ判定で問題が生じます。正規化とは次のような処理を指します:
-
スキーム名やホスト名の小文字化(これらは大文字小文字を区別しない)
-
デフォルトポートの削除(例:http ポート80 を省略)
-
パーセントエンコーディングの正規化(%7E と ~ 等)
-
パスのドットセグメント("./", "../")の解決
ただしパスやクエリの大文字小文字の扱いはサーバ側の実装に依存するため、安易な小文字化は危険です。
実務上の注意点・セキュリティ
-
フラグメント(#以降)はサーバへ送られないため、サーバ側で機密情報をフラグメントで渡す設計は避けるべきです。
-
オープンリダイレクトや不適切な正規化を悪用した攻撃(ディレクトリ・トラバーサル、正規化攻撃)に注意する。URIの検証は慎重に行う。
-
IDN(国際化ドメイン名)を用いたホモグラフ攻撃(見た目が似た文字を使ったフィッシング)に注意。必要なら Punycode 表記を表示するなどの対策を検討。
-
データURI(data:)やjavascript: スキームは XSS のリスクを高めうる。ユーザー入力を直接URIとして扱うときはサニタイズが必須。
-
URI長やブラウザのURL長制限(実際にはブラウザやサーバーにより異なる。IIS/IEでは過去に 2083 文字などの制限が知られているが、現代の実装でも長さには実用的制限がある)を考慮する。
開発・運用でのベストプラクティス
-
資源の識別と位置(名前とロケータ)を明確に分ける。恒久的な識別子(URNや自社の識別体系)と実際の配布URLを分離できる設計が望ましい。
-
URIを生成・処理するライブラリ(標準ライブラリ、WHATWG URL API、URIパーサー)を利用し、独自実装は避ける。
-
ユーザー入力を含むURIは必ずエンコードし、不正なスキーム(javascript: など)をホワイトリストで制限する。
-
公開APIではURIの形式(スキーマ、パス規則、エンコーディング)をドキュメント化して互換性を保つ。
-
クエリパラメータ順序の取り扱いや同値比較ルールを定義してキャッシュや署名検証の不整合を防ぐ。
具体例(簡単なパターン)
-
絶対URI:
https://example.com:443/path/page.html?x=1#section -
相対URI:
../images/photo.png— 基底URIに対して解決される。 -
URN:
urn:isbn:0451450523 -
データURI例:
data:text/plain;charset=utf-8,Hello%20World -
メールリンク:
mailto:info@example.com?subject=Hello%20World
まとめ
URI はインターネット上で資源を識別するための基礎的かつ重要な仕組みです。技術仕様(RFC 3986)に従い、正しいエンコーディング、正規化、相対参照の取り扱いを行うことが、安全で互換性のある設計に不可欠です。開発時には標準ライブラリやブラウザの仕様(WHATWG URL など)を活用し、セキュリティリスク(XSS、ホモグラフ、リダイレクト)に対する対策を講じることを推奨します。
参考文献
- RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
- RFC 2396: Uniform Resource Identifiers (URI): Generic Syntax
- RFC 1738: Uniform Resource Locators (URL)
- RFC 3987: Internationalized Resource Identifiers (IRIs)
- RFC 8141: Uniform Resource Names (URNs)
- MDN: Identifying resources on the Web (URI, URL, URN の解説)
- WHATWG URL Standard(ブラウザのURL処理に関するリビングスタンダード)


