Content-Type ヘッダー - MIMEタイプの基本

入門 | 8分 で読める | 2026.05.02

公式ドキュメント

Content-Typeとは

Content-Typeがtext/html、application/json、multipart/form-data、image/pngなどbodyの解釈方法を伝える図

Content-Typeは、HTTPリクエストまたはレスポンスのボディがどの形式かを示す表現ヘッダーです。送信側は、形式が分かっているボディに適切なメディアタイプを付けます。省略時の扱いは受信側によって異なるため、推測に頼らないことが重要です。

POST /api/users HTTP/1.1
Content-Type: application/json

{"name": "Alice", "email": "alice@example.com"}

役割: リクエストではクライアントからサーバーへ、レスポンスではサーバーからクライアントへ、ボディの解釈方法を伝えます。

MIMEタイプの構造

MIMEタイプは「タイプ/サブタイプ」の形式で表現されます:

type/subtype[; parameter=value]

例:

application/json
text/html; charset=utf-8
multipart/form-data; boundary=----WebKitFormBoundary
要素説明
タイプデータの大分類text, application, image
サブタイプ具体的な形式html, json, png
パラメータ追加情報(オプション)charset=utf-8

ポイント: MIMEタイプは元々メール用の規格(MIME: Multipurpose Internet Mail Extensions)でしたが、HTTPでも採用されました。

よく使うMIMEタイプ一覧

テキスト系

MIMEタイプ説明使用場面
text/htmlHTML文書Webページ
text/plainプレーンテキストログファイル、テキストファイル
text/cssCSSスタイルシート
text/javascriptJavaScriptスクリプトファイル
text/csvCSVデータエクスポート
# HTML
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8

<!DOCTYPE html><html>...

アプリケーション系

MIMEタイプ説明使用場面
application/jsonJSONAPI通信(最重要)
application/xmlXML古いAPI、設定ファイル
application/pdfPDF文書ダウンロード
application/zipZIP圧縮ファイルファイル配布
application/x-www-form-urlencodedURLエンコードフォームHTMLフォーム送信
application/octet-streamバイナリデータ(汎用)ダウンロード
# JSON API
POST /api/users HTTP/1.1
Content-Type: application/json

{"name": "Bob"}

画像・ファイル系

代表例はimage/pngimage/jpegimage/svg+xmlapplication/pdfです。網羅的な一覧が必要な場合は、IANAのMedia Types Registryを確認します。

# 画像レスポンス
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 12345

(バイナリデータ)

charsetパラメータ

テキスト系のMIMEタイプでは、文字エンコーディングを指定できます:

Content-Type: text/html; charset=utf-8

JSONでは通常Content-Type: application/jsonを使います。JSONの登録情報にはcharsetパラメータが定義されておらず、ネットワーク上のJSONはUTF-8を用いるのが基本です。

主な文字エンコーディング:

charset説明
utf-8Unicode(推奨、最も一般的)
iso-8859-1Latin-1(欧米言語)
shift_jisShift JIS(日本語、レガシー)

ポイント: 現代のWebではcharset=utf-8が標準です。特別な理由がない限りUTF-8を使いましょう

application/x-www-form-urlencoded

HTMLフォームのデフォルトエンコーディング方式:

POST /api/login HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=alice&password=YOUR_PASSWORD

特徴:

  • キー=値のペアを&で連結
  • スペースは+または%20に変換
  • 特殊文字はURLエンコード(%エンコード)

制約:

  • ファイルアップロードには使えない
  • バイナリデータには不向き
<!-- HTMLフォーム例 -->
<form method="POST" action="/api/login">
 <input name="username" value="alice">
 <input name="password" type="password">
 <button type="submit">Login</button>
</form>

multipart/form-data

ファイルアップロード用のエンコーディング方式:

POST /api/upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="title"

My Document
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="document.pdf"
Content-Type: application/pdf

(バイナリデータ)
------WebKitFormBoundary7MA4YWxkTrZu0gW--

構造の説明

要素説明
boundaryパート境界の識別子(ランダム文字列)
Content-Dispositionフィールド名とファイル名
Content-Type各パートのMIMEタイプ

注意: boundaryは各パートの区切りを示す重要な値です。データ内に出現しないランダムな文字列を使う必要があります。

HTMLでのファイルアップロード

<form method="POST" action="/api/upload" enctype="multipart/form-data">
 <input type="text" name="title" placeholder="タイトル">
 <input type="file" name="file">
 <button type="submit">アップロード</button>
</form>

JavaScriptでのファイルアップロード

const formData = new FormData();
formData.append('title', 'My Document');
formData.append('file', fileInput.files[0]);

fetch('/api/upload', {
 method: 'POST',
 body: formData
 // Content-Typeは自動設定される(boundary含む)
});

実践メモ: FormDataを使う場合、Content-Typeを手動設定してはいけません。ブラウザが自動的にboundaryを含めて設定します。

Content-Typeの使い分け

APIリクエスト

データ形式Content-Type使用場面
JSONapplication/json現代のREST API
URLエンコードapplication/x-www-form-urlencodedシンプルなフォーム
ファイルありmultipart/form-dataファイルアップロード

APIレスポンス

# JSON
HTTP/1.1 200 OK
Content-Type: application/json

{"status": "success"}

# HTML
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8

<!DOCTYPE html>...

# ファイルダウンロード
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="report.pdf"

よくある間違い

1. Content-Typeの指定忘れ

# ❌ 悪い例
POST /api/users HTTP/1.1

{"name": "Alice"}

サーバーがJSONとして解釈できない可能性があります。

# ✅ 良い例
POST /api/users HTTP/1.1
Content-Type: application/json

{"name": "Alice"}

2. charsetの不一致

# ❌ 悪い例(UTF-8で送っているのにShift_JISと宣言)
Content-Type: text/html; charset=shift_jis

(実際はUTF-8のHTML)

文字化けの原因になります。

3. FormDataにContent-Typeを手動設定

// ❌ 悪い例
const formData = new FormData();
formData.append('file', file);

fetch('/api/upload', {
 method: 'POST',
 headers: {
 'Content-Type': 'multipart/form-data' // boundaryが欠落
 },
 body: formData
});

// ✅ 良い例
fetch('/api/upload', {
 method: 'POST',
 body: formData // Content-Typeは自動設定
});

4. 実データと異なるタイプを返す

画像をtext/htmlとして返すなど、宣言と実データが一致しないと表示失敗や意図しない解釈につながります。特にスクリプトやスタイルを配信するサイトでは、正しいContent-Typeに加えて次のヘッダーでMIME sniffingを無効にする方法があります。

X-Content-Type-Options: nosniff

Content-Typeの判定

サーバー側(Node.js / Express)

app.post('/api/data', (req, res) => {
 if (req.is('application/json')) {
 // JSONとして処理
 console.log(req.body);
 } else if (req.is('multipart/form-data')) {
 // ファイルアップロードとして処理
 console.log(req.files);
 } else {
 res.status(415).send('Unsupported Media Type');
 }
});

クライアント側(JavaScript)

fetch('/api/data')
 .then(response => {
 const contentType = response.headers.get('Content-Type');
 
 if (contentType?.startsWith('application/json')) {
 return response.json();
 } else if (contentType?.startsWith('text/html')) {
 return response.text();
 } else if (contentType?.startsWith('image/')) {
 return response.blob();
 }
 });

まとめ

Content-Typeは、リクエストとレスポンスのボディをどう解釈するか伝えるヘッダーです。JSONはapplication/json、HTMLはtext/html; charset=utf-8、ファイルを含むフォームはmultipart/form-dataを基本にし、宣言と実データを一致させます。

関連記事

参考リソース

← 一覧に戻る
PR
PR
PR
PR