Back

MIME タイプと Content-Type ヘッダーのクイックガイド

MIME タイプと Content-Type ヘッダーのクイックガイド

JavaScript アプリが {"status": "success"} を受信しても、ブラウザがそれを JSON ではなくプレーンテキストとして扱う場合、それは MIME タイプの問題に直面しています。CSS ファイルの読み込みに失敗したり、画像が表示されずにダウンロードされたり、API が予期しない形式でデータを返したりする場合も同じ問題が発生します。これらの問題は、Content-Type ヘッダーMIME タイプの設定ミスに起因します。これらは、ブラウザが受信するすべてのデータを解釈するために使用するシステムです。

このガイドでは、HTTP メディアタイプの仕組み、モダンな Web 開発に必要なタイプ、適切なタイプ処理と X-Content-Type-Options ヘッダーによるセキュリティ脆弱性の防止方法について説明します。

重要なポイント

  • ブラウザはファイル拡張子ではなく Content-Type ヘッダーに依存してレスポンスを解釈する
  • 不正な MIME タイプは CSS の失敗、JavaScript のブロック、API パースエラーを引き起こす
  • X-Content-Type-Options ヘッダーは危険な MIME スニッフィング攻撃を防止する
  • モダンブラウザはセキュリティのために MIME タイプチェックを厳格に実施する

MIME タイプの構造を理解する

MIME タイプ(Multipurpose Internet Mail Extensions type)は、スラッシュで区切られた2つの部分で構成されます:

type/subtype

type は一般的なカテゴリ(text、image、application)を表し、subtype は正確な形式(html、jpeg、json)を指定します。オプションのパラメータで追加情報を提供できます:

text/html; charset=utf-8
application/json; charset=utf-8

重要な原則: ブラウザはファイル拡張子ではなく Content-Type ヘッダーを使用して、レスポンスの処理方法を決定します。data.txt という名前のファイルが Content-Type: application/json で提供される場合、プレーンテキストではなく JSON として解析されます。

フロントエンド開発に必須の MIME タイプ

HTML、CSS、JavaScript

  • text/html - HTML ドキュメント(常に charset を含める)
  • text/css - スタイルシート(<link> タグが機能するために必要)
  • text/javascript - JavaScript ファイル(application/javascript に代わる最新の標準)

API とデータ形式

  • application/json - JSON データ(最も一般的な API 形式)
  • application/xml - XML ドキュメント
  • application/x-www-form-urlencoded - 標準的なフォーム送信
  • multipart/form-data - ファイルアップロードを含むフォーム

画像とメディア

  • image/jpegimage/pngimage/gif - 標準的な画像形式
  • image/svg+xml - SVG グラフィックス
  • image/webpimage/avif - モダンな最適化形式
  • video/mp4audio/mpeg - 一般的なメディアタイプ

フォント

  • font/woff2font/woff - Web フォント形式
  • font/ttffont/otf - 従来のフォントファイル

サーバーが Content-Type ヘッダーを設定する方法

Web サーバーは複数の方法で Content-Type ヘッダーを決定します:

  1. ファイル拡張子のマッピング - サーバーは .htmltext/html に、.jsonapplication/json にマッピングする
  2. 明示的な設定 - 開発者がプログラムでヘッダーを設定する
  3. デフォルトのフォールバック - 不明なファイルはデフォルトで application/octet-stream になる

Node.js/Express での例:

res.setHeader('Content-Type', 'application/json; charset=utf-8');
res.json({ status: 'success' });

Nginx や Apache のような静的ファイルサーバーは、設定ファイルを使用して拡張子を MIME タイプにマッピングします。CDN やオブジェクトストレージサービス(S3、Cloudflare)は通常、ファイル拡張子に基づいてこれらを自動的に設定します。

MIME タイプが間違っている場合に起こること

不正な Content-Type ヘッダーは、即座に目に見える問題を引き起こします:

  • CSS が無視される: CSS を text/plain として提供すると、スタイルの読み込みが妨げられる
  • JavaScript がブロックされる: 間違ったタイプは CORS エラーや実行の失敗を引き起こす
  • JSON がテキストとして解析される: API がオブジェクトではなく文字列を返す
  • 画像がダウンロードされる: ブラウザが表示する代わりにファイルをダウンロードする
  • セキュリティ脆弱性: 不正なタイプは XSS 攻撃を可能にする

モダンブラウザはセキュリティのために MIME タイプチェックを厳格に実施します。Chrome や Firefox は、不正な Content-Type ヘッダーを持つスタイルシートやスクリプトの実行を拒否し、「Refused to apply style from ’…’ because its MIME type (‘text/plain’) is not a supported stylesheet MIME type.」のようなコンソールエラーを表示します。

セキュリティ: MIME スニッフィングと X-Content-Type-Options

MIME スニッフィングは、ブラウザが Content-Type ヘッダーを無視し、コンテンツを調べてファイルタイプを推測する際に発生します。時には役立つこともありますが、この動作は深刻なセキュリティリスクを生み出します。

攻撃者は、HTML と JavaScript を含む image.jpg という名前のファイルをアップロードする可能性があります。サーバーが Content-Type: image/jpeg を送信しても、ブラウザが HTML コンテンツを検出してレンダリングすると、悪意のあるスクリプトが実行されます。

MIME スニッフィングの防止

常に X-Content-Type-Options ヘッダーを含めてください:

X-Content-Type-Options: nosniff

このヘッダーは、ブラウザに宣言された Content-Type を尊重するよう強制し、推測を防ぎます。特に以下の場合に重要です:

  • ユーザーがアップロードしたコンテンツ
  • API レスポンス
  • 動的コンテンツ生成
  • CDN から提供されるファイル

実装例:

// Express ミドルウェア
app.use((req, res, next) => {
  res.setHeader('X-Content-Type-Options', 'nosniff');
  next();
});

よくある問題のトラブルシューティング

問題: API が JSON をテキストとして返す

解決策: サーバーが Content-Type: application/json を送信することを確認する

問題: フォントがクロスオリジンで読み込めない

解決策: フォントファイルに正しい MIME タイプと CORS ヘッダーを設定する

問題: SVG 画像がテキストとして表示される

解決策: text/xml ではなく image/svg+xml を使用する

問題: 表示ではなくダウンロードがトリガーされる

解決策: Content-Disposition: attachment ヘッダーを削除し、正しい MIME タイプを使用する

デバッグツール

  • ブラウザの DevTools ネットワークタブで実際の Content-Type ヘッダーを表示
  • curl -I [url] でレスポンスヘッダーを検査
  • オンライン MIME タイプバリデーターでサーバー設定を確認

まとめ

正しい MIME タイプと Content-Type ヘッダーは、Web 機能の基本です。これらは、ブラウザがコンテンツを解析、実行、またはダウンロードするかを決定します。適切な HTTP メディアタイプを設定することで、レンダリングの失敗、API エラー、セキュリティ脆弱性を防ぎます。覚えておいてください: ブラウザはファイル拡張子よりも Content-Type ヘッダーを信頼し、MIME スニッフィングはセキュリティリスクを生み出し、X-Content-Type-Options: nosniff ヘッダーは本番アプリケーションに不可欠です。

信頼性の高い Web アプリケーションのために、常に Content-Type ヘッダーを明示的に設定し、デプロイメントパイプラインで MIME タイプを検証し、異なるブラウザでテストして一貫した動作を確保してください。

よくある質問

ブラウザはファイル拡張子を無視し、Content-Type ヘッダーのみを使用します。サーバーはレスポンスヘッダーで Content-Type: application/json を明示的に送信する必要があります。サーバー設定を確認するか、バックエンドコードでプログラム的にヘッダーを追加してください。

このヘッダーがない場合、ブラウザは MIME スニッフィングを実行し、安全なファイルタイプに偽装された悪意のあるコードを実行する可能性があります。これは特にユーザーアップロードで XSS 脆弱性を生み出します。常に X-Content-Type-Options: nosniff を設定して、ブラウザに宣言された Content-Type を尊重させてください。

application/javascript はかつて推奨されていましたが、現在の HTML 仕様では JavaScript ファイルに text/javascript を推奨しています。モダンブラウザは両方を受け入れますが、text/javascript は最大限の互換性を保証し、現在の標準に従っています。

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay