Yuki's Tech Blog

仕事で得た知見や勉強した技術を書きます。

【Webを支える技術】第2部 URIをざっくりまとめてみた

目次

URIとは何か?

URIとは、リソース(Web上の情報)にアクセスするためのIDです。リソースを一意に識別できます。

URIの書式

http://blog.example.jp/entries/1
名前 URIを構成するパーツ 意味
URIスキーム http URIスキームは、そのURIが利用するプロトコルを表します。httpの場合、リソースにHTTPでアクセスできることが分かります。
ホスト名 blog.example.jp ホスト名の部分には、DNSで名前が解決できるドメイン名かIPアドレスがきます。インターネット上のIPアドレスグローバルIPアドレスなので、ホストはインターネット上で必ず一意になります。
ポート番号 80 ホスト名の後ろに:で区切ってポート番号を書くことができます。ポート番号は、このホストにアクセスするときのプロトコルで使用する番号です。ポート番号を省略すると、そのプロトコルで使用するデフォルトのポート番号が使われます。HTTPのデフォルトのポート番号は80番です。
パス /entries/1 ホストの中における一意なリソースを表します。リソースは一意であるべきなので、ホストの中で同じリソースが複数存在するのは良くないです。

Tips

  • URIスキームとその後ろに続く部分は「://」で区切られます。
  • インターネット上で一意なホスト、ホスト上で一意なリソースなので、あるリソースのURIは他のリソースのURIと重複しないようになっています。
  • ホストとは、ネットワークに接続されたコンピュータのことです。ホストにはIPアドレスが設定されています。

URI・URL・URNの違いは何か?

名称 意味
URI URIとURNを合わせたもの
URL リソースの一意な位置を表す
URN リソースの一意な名前を表す

URNはあまり利用されていないので、実質的にはURIとURLはほぼ同じ意味です。

絶対URIと相対URIの違い

OSのファイルシステムには、絶対パス相対パスがあります。 相対パスを使うことで、ディレクトリやファイルの位置をルートディレクトリ( / )から書かずに、カレントディレクトリから指定できます。カレントディレクトリをbar、親ディレクトリをfooとする場合、相対パス絶対パスは以下のようになります。

相対パス 絶対パス
hoge /foo/bar/hoge
hoge/fuga /foo/bar/hoge/fuga
./hoge /foo/bar/hoge
../hoge /foo/hoge
../hoge/fuga /foo/hoge/fuga
../../hoge /hoge

OSのファイルシステムと同様に、URIにも絶対URIと相対URIがあります。 相対URIは、URIスキームとホスト名を省いた、パスだけのURIです。相対URIでもリソースの位置を指定できます。クライアントは相対URIを理解できないので、相対URIを使うにはベースURI(http://example.jp/foo/bar)が必要です。相対URIは、ベースURIを用いて絶対URIに変換してリソースにアクセスしているので、ベースURIは必要です。

相対URI 絶対URI 備考
/foo/bar http://example.jp/foo/bar
hoge http://example.jp/foo/bar/hoge ./hogeで同じ
../hoge http://example.jp/foo/hoge
?q=hoge http://example.jp/foo/bar?q=hoge
#hoge http://example.jp/foo/bar#hoge #から始まる文字列は「URIフラグメント」と言う

Tips

相対URIの前に/がある場合、この相対URIは、ホスト名以降のパスを示していることになります。

2つのベースURIの与え方

リソースのURIをベースURIとする

あるリソースを取得時、そのリソース内で相対URIが出てきたら、取得したリソースのURIをベースURIとするやり方です。しかし、この方法ではリソースのURIをクライアント側で保存する必要があります。リソースを取得したときのURIは保存時にはわからないので、この方法は成立しません。

ベースURIを明示的に指定する。

HTMLやXMLの中で明示的にベースURIを指定する。HTMLの場合、要素の中に要素を入れます。このやり方の場合、先ほどの問題を解決できます。

<html xmlns="http://www.w3.org/2022/xhtml">
  <head>
    <title>test web page</title>
    <! -- このHTML文書内のベースURIはhttp://example.jp/になる -->
    <base href="http://example.jp/" />
    ...
  </head>
  ...
</html>

Ruby on RailsにおけるベースURI

APIモードとして使う場合、絶対URIAPIにリクエストを出します。 フルスタックフレームワークとして使う場合、base要素にベースURIを指定するやり方で相対URIを解決しています。base要素の指定がない場合、location.hrefの値がデフォルトのベースURIになります。Railsのapplication.html.erbにはbase要素が指定されていませんが、暗黙的にlocation.hrefの値がベースURIになっています。 Image from Gyazo

相対URIをホバーすると、絶対URIが表示される

URIで利用できる文字以外をURIに含めたい場合

URIで利用できる文字は、アスキー文字だけです。半角の英字(a~z、A~Z)やアラビア数字(0~9)、記号、空白文字、制御文字など128文字が規定されています。

アスキー(ASCII)文字

種類 アスキー文字
アルファベット A-Za-z
数字 0-9
記号 -.~:@!$&'()

アスキー文字以外をURIに入れたい場合、%エンコーディングをします。%エンコーディングでその文字をエンコードします。

Tips

良いURLとは何か?

良いURIとは、「変わらないURL」です。「変わりにくいURL」と捉えることもできます。変わらないURLにすることによって、システムやドメインの変更が起きても、リンク切れを回避することができます。また、良いURIは、シンプルです。シンプルであると、入力するのが簡単で覚えやすいです。

URIの設計指針

どうしてもURIを変更したい場合

できる限り古いURIから新しいURIへリダイレクトします。

  • 変更前
http://example.jp/old
  • 変更後
http://example.jp/login

古いURIでクライアントがリクエストを出すと、次のレスポンスが返ります。

HTTP/1.1 301 Moved Permanetly
Location: http://example.jp/login

クライアントは、ステータスコードからリダイレクトであることを理解し、Locationヘッダで明示された新しいURIにリクエストを出します。 リダイレクトを実現する仕組みはHTTPサーバが用意しています。

マトリクスURIとは?

マトリクスURIとは、複数の軸のパラメータをセミコロンやカンマで区切ってリソースを表現するURIです。リソースを階層構造で表現できない場合に使用します。Googleマップで緯度や経度を表す時に使います。以下のURLでは、パラメータの順序で緯度・経度を指定しています。

https://www.google.com/maps/@34.6794753,126.7831703,5.26z?hl=ja

URIは不透明であるべき。

ユーザーが適当にURIを入力して有料会員限定のコンテンツが見れる等を防ぐため、URIからリソースの内容を推測されないようにするのが大事です。

参考記事

<base>&colon; 文書の基底 URL 要素 - HTML&colon; HyperText Markup Language | MDN

パーセントエンコーディング - Wikipedia