Web サーバーの動作メカニズム
Web の動作を理解するには、ネットワーク通信の基本となるソケットプログラミングを知る必要があります。クライアント(ブラウザ)がリクエストを送信し、サーバーが応答を返すという流れを Python の標準ライブラリで簡易的に実装してみます。
# web_server.py
import socket
def start_web_server(host='127.0.0.1', port=8080):
# ソケットオブジェクトの作成
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# アドレスとポートのバインド
server_socket.bind((host, port))
# リスニング状態に変更(最大接続キュー長は 5)
server_socket.listen(5)
print(f"Listening on {host}:{port}")
try:
while True:
# クライアントからの接続を受け取る
client_conn, client_addr = server_socket.accept()
try:
# データを受信
request_data = client_conn.recv(1024)
# 固定の HTML コンテンツを読み込む
response_body = b"<html><body><h1>Connection Successful</h1></body></html>"
# HTTP レスポンスヘッダーを作成して送信
http_header = b"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"
client_conn.send(http_header + response_body)
finally:
client_conn.close()
except KeyboardInterrupt:
print("Shutting down server...")
finally:
server_socket.close()
if __name__ == "__main__":
start_web_server()
上記のようなサーバーを起動した後、ブラウザからローカルアドレス(例:127.0.0.1:8080)にアクセスすると、サーバーが定義した HTML がレンダリングされます。この一連のプロセスは「リクエスト→レスポンス」モデルと呼ばれます。
HTML の概要と特性
HTML(HyperText Markup Language)は、ウェブページを作成するためのマークアップ言語です。
- プログラミング言語ではなく、構造を記述するための規則集です。
- ブラウザが解釈できるタグ形式で書かれます。
- ファイル拡張子は一般的に
.htmlまたは.htmです。
重要なのは、ブラウザによってタグの描画処理がわずかに異なる可能性があるため、クロスブラウザ対応を意識することです。
HTML ドキュメントの基本構造
標準的な HTML5 の骨格は以下の通りです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ページのタイトル</title>
</head>
<body>
<!-- ページに表示される内容 -->
</body>
</html>- <!DOCTYPE html>: HTML5 であることを宣言します。必ず先頭に置きます。
- <html>: ルート要素で、コンテンツ全体を囲みます。
- <head>: メタデータや外部ファイルへのリンクを定義します。画面には直接表示されません。
- <title>: タブやブックマークに表示されるタイトルです。
- <body>: ユーザーに見える本体のコンテンツが入ります。
注記:日本語サイトでは文字化け防止のため、UTF-8 エンコーディングを明示するのが一般的です。
タグの構文と属性
タグは角括弧 < > で挟みます。基本的に開始タグと終了タグのペアで存在しますが、空要素(自己完結型)もあります。
- ペア形式:
<div>...内容.../</div> - 単独形式:
<br>,<img>など
主要な属性
| 属性名 | 説明 |
|---|---|
| id | ドキュメント内での一意な識別子。JavaScript 操作などで使用。 |
| class | CSS スタイル適用やグループ化のために使用するクラス名。 |
| style | その要素に対するインライン CSS を記述できます。 |
一般的なタグ分類
HEAD 領域の主なタグ
| タグ | 用途 |
|---|---|
| <meta> | 文字セット設定やキーワード指定などメタ情報。 |
| <link> | CSS ファイルなどの外部リソース読み込み。 |
| <script> | JavaScript コードの実装または読み込み。 |
| <base> | 相対パスの基準 URL を指定。 |
BODY 領域:ブロック要素とインライン要素
HTML 要素はレイアウト振る舞いにより分類されます。
- ブロック要素 (Block)
- 常に関数の上から行を改行して配置。
- 幅(width)、高さ(height)、margin/padding の制御が可能。
- 例:
div,p,h1-h6,ul
- インライン要素 (Inline)
- 同じ行内で並べて表示。
- サイズ変更や上下のマージンは原則不可。
- 例:
span,a,img,strong
テキスト関連タグ
<h1>〜<h6>: ヘッダー(重要性順)<p>: パラグラフ<br>: 強制改行<hr>: 水平線<pre>: 書式維持テキスト
リンクとメディア
画像 (<img>):
<img src="/images/photo.jpg" alt="説明文" width="300" height="200">src: リソースパスalt: 画像が表示されない場合の代替テキスト
アンカー (<a>):
<a href="https://example.com/page" target="_blank">リンク先</a>href: 移動先 URL(絶対・相対・アノテーション可能)target:_blank(新タブ)または_self(現在タブ)
リストとテーブル
リストの表現
<!-- 順序なしリスト -->
<ul type="disc">
<li>項目 A</li>
<li>項目 B</li>
</ul>
<!-- 順序付きリスト -->
<ol type="1">
<li>第一ステップ</li>
<li>第二ステップ</li>
</ol>表データの表示
行列形式のデータを表示する場合に使用します。
<table border="1">
<tr>
<th>項目名</th>
<th>値</th>
</tr>
<tr>
<td colspan="2">結合されたセル</td>
</tr>
</table>colspan: 列の結合(横方向)rowspan: 行の結合(縦方向)
フォーム入力機能
ユーザーからのデータ収集を行うためのインターフェースです。
フォームタグと送信用途
<form action="/submit-handler" method="POST" enctype="multipart/form-data">
</form>action: 送信先のサーバーアドレスmethod: GET(URL に含まれる)または POST(リクエストボディへ)
Input 要素のタイプ
| Type | 機能 |
|---|---|
| text | 単一行テキスト入力 |
| password | マスク処理されたパスワード入力 |
| radio | 複数選択肢から一つ選択 |
| checkbox | 複数選択肢を同時に選択可能 |
| file | ファイルアップロード用 |
| hidden | 非表示の状態でデータを渡す |
Select と Textarea
<select>: ドロップダウンリスト。<option>で選択肢を定義。<textarea>: 多行テキストエリア。行数や列数を指定可能。
バックエンドとの連携イメージ
フォームで送信されたデータはサーバーサイド言語(Python/Django など)で処理されます。以下はファイルをアップロードする際のエンドポイント設計の一例です。
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('api/upload/', views.handle_upload, name='upload'),
]
# views.py
from django.http import HttpResponse
def handle_upload(request):
if request.method == 'POST':
file_obj = request.FILES.get('uploaded_document')
if file_obj:
filename = file_obj.name
# バイナリ書き込み処理(実際の環境では保存経路が必要です)
with open(filename, 'wb+') as destination:
for chunk in file_obj.chunks():
destination.write(chunk)
return HttpResponse('アップロード完了')
return HttpResponse('リクエスト受け付け済み')フォーム入力要素には label タグを使ってアクセシビリティを向上させることが推奨されます。また、fieldset と legend を使うことでフォーム内のセクション分割が可能になります。