URI(URL)をRFC3986から理解しよう
サイト作っていると、時々URLが%だらけのよくわからないものになってしまう。
英語使えば回避できるんだけど、そもそもこれって何だろうと今更気になったので調べてみました。
URI、URL、URN
まずはURIとURL、URNの役割について以下から簡単にでも理解いただければと思います。
なぜかというと、URIについて取り上げているRFC3986にて、URLやURNの構文に関する仕様を取り扱っているからです。
RFC3986
1998年にURIに関する初めての標準化ドキュメントとしてRFC2396が公開されました。
RFC2396ではURIを構成する7つの構成要素(スキーム、オプションの認証情報、ホスト、ポート、パス、クエリ、およびフラグメント)について、定義しています。
その後2005年にRFC2396を置き換える形でRFC3986が公開されました。
主な改善点として、あいまいであったルールの厳格化、セグメントの処理の改善、新しい構文要素の追加などが挙げられます。
今回はこのRFC3986に記載のあるURIの構文について勉強していきます。
URIの構成要素
URIはスキーム、認証情報、ホスト、ポート、パス、クエリ、フラグメントの7つの要素から構成されます。
各要素は以下の役割を持っています。
要素 | 概要 | 例 |
---|---|---|
スキーム(Scheme) | URIが示すリソースへのアクセス方法を定義するプロトコル名 スキームは、URIの最初のコロン「:」までの文字列で表す | http:、https:、ftp: |
認証情報 (Userinfo) | リソースにアクセスするために必要なユーザー名やパスワードなどの認証情報 認証情報は、スキームの後に続く「 //」 の後、ホストの前にコロン「:」で区切られた文字列で表すまた、認証情報の後には、認証情報であることを示す「@」を付与する オプションであり必ずしも必要ではない | ftp://user:password@example.com |
ホスト (Host) | リソースが配置されているホスト名やIPアドレスを表す ホストは、スキームの後に続く「 //」 の後、オプションの認証情報の後、パスの前にある文字列で表す | ftp://user:password@example.com |
ポート (Port) | リソースにアクセスするために使用するポート番号 ポートは、ホストの後に続くコロン「:」で区切られた数字で表す オプションであり必ずしも必要ではない | http://example.com:8080 |
パス (Path) | リソースの場所を表すパス名 パスは、ホストの後に続くスラッシュ「/」から始まる文字列で表す | https://example.com/path/to/resource.html |
クエリ (Query) | URIが参照するリソースに関する情報 クエリは、パスの後に続く ? で始まる文字列で表すまた、名前と値のペアで構成され、各ペアは「 =」 で区切られる複数のペアは「 &」 で区切られる一般的に検索やフィルタリングなどの目的で使用される | https://example.com/search?q=apple&category=fruit |
フラグメント (Fragment) | URI内の特定の部分を示すために使用される識別子 (要するにサイトの目次で章をクリックしたらその章に飛ぶようなリンク) URIの最後に 「#」 に続いて指定される | https://www.example.com/page.html#section2 |
URIにおける「///」
RFC3986では認証情報、ホスト名、ポート番号を含むオプションのことをAuthorityと呼びます。
そして、このAuthorityの前、あるいはスキームの後には必ず「//」をつける必要があります。
このAuthorityは用途によっては省略することが出来、その場合スキームの後のスラッシュは「///」となります。
試しにブラウザへ「file:///C:/」を入力してみると、Cドライブがブラウザ上で確認できます。
これは「//」と「/」(パスのルート)が連続することでホスト名を省略してパスを指定し、ローカルフォルダを表示しています。
パーセントエンコーディング
RFC3986では、URIに含まれる文字のエンコーディング方式としてパーセントエンコーディングが定義されています。
パーセントエンコーディングは、URIに含まれる非ASCII文字や予約文字、制御文字、スペースなどの特殊な文字を、安全にURIに組み込むために使用されます。
パーセントエンコーディングは、以下の3つのステップから構成されます。
- 文字のバイト表現をUTF-8などのエンコーディング方式でエンコードする。
- エンコードされたバイト表現を16進数表記に変換する。このとき、各バイトの先頭に「%」を付ける。
- URI中の各文字を、エンコードされた16進数表記に置き換える。
たとえば、日本語の「こんにちは」をURIに含める場合、以下のようにパーセントエンコーディングを使用してエンコードします。
- 文字列「こんにちは」をUTF-8でエンコードすると、「e3 81 93 e3 82 93 e3 81 ab e3 81 a1 e3 81 af」となる。
- 各バイトの16進数表記を「%」を付けて置き換えると、「%e3%81%93%e3%82%93%e3%81%ab%e3%81%a1%e3%81%af」となる。
- URI中の「こんにちは」を「%e3%81%93%e3%82%93%e3%81%ab%e3%81%a1%e3%81%af」に置き換える。
最後に
日頃よく見るURLにこんな意味があったのかとためになりました。
また、pythonなんかでパーセントエンコーディングを扱う際には以下が比較的参考になります。