この記事の要点
• URLはscheme://userinfo@host:port/path?query#fragmentの要素で構成される
• URIは識別子全般、URLは場所を示すURIのサブセット
• 特殊文字はパーセントエンコーディング(%20など)でエスケープする
URLとは
URL(Uniform Resource Locator)は、インターネット上のリソース(Webページ、画像、APIエンドポイントなど)の場所を示す住所です。ブラウザのアドレスバーに入力する文字列がURLです。
なぜ重要か: URLは人間が覚えやすく、機械が解釈できる統一された形式でリソースを指定します。Webの基盤となる技術の一つです。
URLの基本構造
完全なURLは以下の要素で構成されます。
https://user:pass@www.example.com:443/path/to/page?key=value&lang=ja#section
└─┬─┘ └───┬───┘ └──────┬──────┘└┬┘└─────┬─────┘└──────┬──────┘└───┬───┘
scheme userinfo host port path query fragment
各要素の役割
| 要素 | 必須 | 役割 | 例 |
|---|---|---|---|
| scheme | ○ | 使用するプロトコル | https, http, ftp, mailto |
| userinfo | × | ユーザー認証情報 | user:pass |
| host | ○ | サーバーのドメイン名またはIPアドレス | www.example.com, 192.168.1.1 |
| port | × | ポート番号(デフォルトは省略可) | 443, 8080 |
| path | × | リソースへのパス | /path/to/page |
| query | × | パラメータ(?以降) | key=value&lang=ja |
| fragment | × | ページ内の位置(#以降) | section |
ポイント: schemeとhostは必須、他の要素はオプションです。ポート番号は省略すると各プロトコルのデフォルトポート(HTTP=80、HTTPS=443など)が使われます。
scheme(スキーム)
使用するプロトコルを指定します。大文字小文字は区別されません(慣例として小文字)。
主要なスキーム
| scheme | 用途 | デフォルトポート |
|---|---|---|
http | 暗号化なしのWeb通信 | 80 |
https | TLS/SSL暗号化されたWeb通信 | 443 |
ftp | ファイル転送プロトコル | 21 |
mailto | メールアドレス | なし |
file | ローカルファイルシステム | なし |
ws | WebSocket | 80 |
wss | 暗号化WebSocket | 443 |
# 具体例
https://example.com/ # Webページ
ftp://ftp.example.com/files # FTPサーバー
mailto:info@example.com # メール送信
file:///C:/Users/doc.pdf # ローカルファイル
セキュリティのヒント: 2024年以降、主要ブラウザは
http://を「安全でない」と警告します。本番環境では常にhttps://を使用しましょう。
userinfo(ユーザー情報)
ユーザー名とパスワードを含む認証情報です。user:password@の形式で記述します。
ftp://admin:secret123@ftp.example.com/files
└───┬───────┘
userinfo
注意: URLに平文のパスワードを含めるのは非常に危険です。HTTPSでも履歴やログに残ります。現代のWebアプリでは使用しないでください。
host(ホスト)
サーバーのドメイン名またはIPアドレスを指定します。
ドメイン名の例
www.example.com # サブドメイン.ドメイン.TLD
api.example.co.jp # 日本のドメイン
localhost # ローカルマシン
IPアドレスの例
http://192.168.1.1/ # プライベートIPv4
http://[2001:db8::1]/ # IPv6([]で囲む)
IPv6の注意: IPv6アドレスは
:を含むため、URLでは[]で囲みます。例:http://[::1]:8080/
port(ポート番号)
サーバーの待ち受けポート番号です。省略すると各プロトコルのデフォルトが使われます。
デフォルトポート
| プロトコル | デフォルトポート | 明示例 |
|---|---|---|
| HTTP | 80 | http://example.com:80/ |
| HTTPS | 443 | https://example.com:443/ |
| FTP | 21 | ftp://example.com:21/ |
| SSH | 22 | ssh://example.com:22/ |
# ポート番号を明示する例
http://localhost:3000/ # 開発サーバー
https://api.example.com:8443/ # カスタムポート
実践メモ: 開発環境では8000、3000、5000など非標準ポートを使うことが多いです。本番環境では通常80/443を使用します。
path(パス)
サーバー内のリソースへのパスです。/で区切られた階層構造です。
/index.html # ファイル
/products/123 # RESTful API(IDが123の商品)
/blog/2025/01/post # 階層構造
/ # ルート
パスの正規化
# これらは同じリソースを指す
/path/./to/../page → /path/page
/path//to///page → /path/to/page
大文字小文字の扱い: UNIXサーバーでは
/Pathと/pathは別物です。Windowsサーバーでは同一です。移植性のため小文字を推奨します。
query(クエリ文字列)
?の後に記述するパラメータです。key=valueの形式で、複数のパラメータは&で区切ります。
?search=keyword # 単一パラメータ
?name=John&age=30&city=Tokyo # 複数パラメータ
?tags[]=web&tags[]=api # 配列形式
クエリパラメータの用途
| 用途 | 例 |
|---|---|
| 検索条件 | ?q=javascript&sort=date |
| ページネーション | ?page=2&limit=20 |
| フィルタリング | ?category=tech&lang=ja |
| トラッキング | ?utm_source=email&utm_campaign=sale |
特殊文字のエンコーディング
// JavaScriptでのエンコード
encodeURIComponent('Hello World') // → "Hello%20World"
encodeURIComponent('日本語') // → "%E6%97%A5%E6%9C%AC%E8%AA%9E"
encodeURIComponent('?&=') // → "%3F%26%3D"
ポイント: クエリ文字列で特殊文字(空白、日本語、記号など)を使う場合は必ずパーセントエンコーディングが必要です。
fragment(フラグメント)
#の後に記述するページ内の位置です。サーバーには送信されず、ブラウザ内でのみ使用されます。
https://example.com/page#section-3 # ページ内のセクションへジャンプ
https://example.com/docs#installation # アンカーリンク
フラグメントの用途
| 用途 | 例 |
|---|---|
| ページ内リンク | #top, #contact |
| SPA(Single Page Application)のルーティング | #/users/123 |
| 状態の保存 | #tab=settings |
サーバーとの通信: フラグメントはHTTPリクエストに含まれません。サーバーはフラグメント部分を認識できません。
URIとURLの違い
URI(Uniform Resource Identifier)はURLを含む上位概念です。
| 用語 | 意味 | 例 |
|---|---|---|
| URI | リソースを識別する文字列全般 | https://example.com/page, urn:isbn:0-486-27557-4 |
| URL | リソースの場所を示すURI | https://example.com/page |
| URN | リソースの名前を示すURI | urn:isbn:0-486-27557-4 |
URI
├── URL(場所で識別): https://example.com/page
└── URN(名前で識別): urn:isbn:978-4-12-345678-9
実務では: ほとんどの場合「URL」と呼べば十分です。厳密な議論では「URI」を使います。
パーセントエンコーディング
URLで使えない文字や予約文字を%XX形式でエンコードします。
エンコードが必要な文字
| 文字 | エンコード | 理由 |
|---|---|---|
| 空白 | %20 | URLに空白は使えない |
# | %23 | フラグメント識別子として予約 |
? | %3F | クエリ文字列の開始として予約 |
& | %26 | クエリパラメータの区切りとして予約 |
= | %3D | クエリパラメータのkey=valueとして予約 |
% | %25 | エンコード記号として予約 |
| 日本語 | %E6%97%A5 など | ASCII範囲外 |
# 実際の例
https://example.com/search?q=Hello%20World # 空白
https://example.com/search?q=%E6%A4%9C%E7%B4%A2 # 「検索」
https://example.com/path?url=https%3A%2F%2Fother.com # URL自体を含む
相対URLと絶対URL
絶対URL
完全なURL(scheme、host を含む)です。
https://www.example.com/path/to/page
相対URL
現在のページを基準にした相対パスです。
# ベースURL: https://example.com/docs/guide/index.html
./images/logo.png → https://example.com/docs/guide/images/logo.png
../api/users → https://example.com/docs/api/users
/about → https://example.com/about
?page=2 → https://example.com/docs/guide/index.html?page=2
#section → https://example.com/docs/guide/index.html#section
相対URLの種類
| 形式 | 説明 | 例(ベース: /docs/guide/page.html) |
|---|---|---|
/path | ルートからの絶対パス | /about → https://example.com/about |
./path | 現在のディレクトリからの相対パス | ./images/logo.png |
../path | 親ディレクトリからの相対パス | ../api/users |
path | 現在のディレクトリからの相対パス | images/logo.png |
?query | 現在のパスにクエリを追加 | ?page=2 |
#fragment | 現在のページのフラグメント | #section |
ポイント: HTMLの`
URLの例
Webページ
https://www.example.com/blog/2025/01/post?page=2#comments
API エンドポイント
https://api.example.com/v1/users/123?fields=name,email
ローカル開発環境
http://localhost:3000/admin/dashboard?debug=true
メールアドレス
mailto:contact@example.com?subject=Hello&body=Message
データURI(Base64エンコード画像)
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...
URLの検証と解析
JavaScriptでの解析
const url = new URL('https://user:pass@example.com:8080/path?key=value#section');
console.log(url.protocol); // "https:"
console.log(url.hostname); // "example.com"
console.log(url.port); // "8080"
console.log(url.pathname); // "/path"
console.log(url.search); // "?key=value"
console.log(url.hash); // "#section"
console.log(url.username); // "user"
console.log(url.password); // "pass"
Pythonでの解析
from urllib.parse import urlparse
url = urlparse('https://example.com:8080/path?key=value#section')
print(url.scheme) # 'https'
print(url.netloc) # 'example.com:8080'
print(url.path) # '/path'
print(url.query) # 'key=value'
print(url.fragment) # 'section'
よくある間違いと注意点
エンコード漏れ
❌ https://example.com/search?q=Hello World # 空白がそのまま
✅ https://example.com/search?q=Hello%20World # 正しくエンコード
二重エンコード
❌ encodeURIComponent(encodeURIComponent("検索")) # %25E6%25... (二重)
✅ encodeURIComponent("検索") # %E6%... (正しい)
ポート番号の誤解
https://example.com:80/ # HTTPSなのにポート80(誤り)
http://example.com:443/ # HTTPなのにポート443(誤り)
注意: URLの長さには制限があります。ブラウザやサーバーによりますが、2000文字を超えると問題が起きる可能性があります。
まとめ
URLはscheme://userinfo@host:port/path?query#fragmentの要素で構成されます。schemeとhostは必須で、他はオプションです。特殊文字はパーセントエンコーディングでエスケープし、相対URLを使うことでコードの保守性を高められます。URLはWebの基盤技術であり、正しく理解することで堅牢なWebアプリケーションを構築できます。
参考リソース
- RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax
- MDN - What is a URL?
- WHATWG - URL Standard
- MDN - encodeURIComponent()