MENU

Content-Type — ボディのMIMEタイプを示すヘッダ

Content-Type アイキャッチ
Content-Type

Content-Typeは、HTTPメッセージのボディが「どんな種類のデータか」を示すヘッダで、MIMEタイプ(Media Type)の形式で記述されます。Content-Type: text/html; charset=UTF-8Content-Type: application/jsonContent-Type: image/pngのような形で送られ、受信側はこれを見てパース方法・レンダリング方法・処理方法を決めます。MIMEは元々1992年のRFC 1341で電子メール向けに定義された仕組みですが、HTTPでも流用され、現在はIANAがtype/subtype形式で公式登録を管理しています。テキストには文字コードを示すcharsetパラメータも付与可能で、Web上のあらゆるデータの「自己紹介」を担う中心的なヘッダです。

目次

この記事の目次

  1. MIMEタイプの構造
  2. MIMEの起源とWebでの普及
  3. 実装現場でのよくある罠
  4. Content-Type vs ファイル拡張子 vs 内容判定
  5. まとめ

MIMEタイプの構造

MIMEタイプの構造

MIMEタイプは「type/subtype」形式で構成されます。typeの大分類はtext(テキスト)、application(アプリ固有データ)、image(画像)、audio(音声)、video(動画)、multipart(複数パート)、message(メッセージ)、font(フォント)、modelの9種類です。subtypeは具体的な形式を表し、text/html・text/css・text/plain・application/json・application/pdf・image/png・image/jpegといった膨大な種類が登録されています。

パラメータは;で区切って追加でき、最も頻出するのはcharset(文字エンコーディング)です。Content-Type: text/html; charset=UTF-8はHTMLがUTF-8で符号化されていることを示し、ブラウザはこれを見てデコードします。multipart/form-data用のboundaryパラメータ(パート区切り文字列の指定)や、application/vnd.api+jsonのようなベンダー固有subtype、+xmlや+jsonのsuffixを使った合成typeなど、形式上の表現力が豊富です。RFC 6838(2013年)でMIMEタイプの登録手続きが標準化され、IANAが3つの登録ツリー(標準・ベンダー・個人)で管理しています。

MIMEの起源とWebでの普及

MIMEの起源とWebでの普及

MIME(Multipurpose Internet Mail Extensions)は1992年6月のRFC 1341で電子メールに添付ファイルや非ASCIIテキストを含めるための仕組みとして定義されました。当時の電子メールはASCIIテキストしか扱えなかったため、画像や日本語などをBase64などで符号化して送るための枠組みが必要でした。MIMEは1996年11月にRFC 2045〜2049として再整理され、HTTPでもボディ種別の表現として採用されました。

1996年5月のHTTP/1.0(RFC 1945)でContent-TypeヘッダがMIMEタイプ形式を取ることが定められ、Webコンテンツの種別表現が統一されました。1999年のHTTP/1.1(RFC 2616)でその位置付けがより明確化され、現代仕様(RFC 9110、2022年)にも引き継がれています。登録手続きは2013年1月のRFC 6838で再整理され、IANAのMedia Types Registryには現在2000を超えるMIMEタイプが登録されています。GeoJSON(application/geo+json)やWebAssembly(application/wasm)など、新しい技術が登場するたびに対応するMIMEタイプが追加されており、Webの拡張性を支えている仕組みです。

実装現場でのよくある罠

実装現場でのよくある罠

REST APIではContent-Type: application/jsonの指定が標準で、これがないとフレームワークが自動JSONパースをしないことがあります。Express・Spring・Djangoなど多くのフレームワークはContent-Typeを見てルーティングやパーサー選択を行うため、APIサーバ・クライアント双方で正しい値を設定することが基本です。Content-Type: text/html; charset=UTF-8のcharset明示は文字化け防止の必須要素で、Apache・Nginxは多くの場合デフォルトでUTF-8を返す設定が推奨されます。

ブラウザにはMIME Sniffing(Content-Typeを信用せずに本文の先頭バイトから種別を推測する挙動)があり、これがXSS(HTMLとして実行されることを意図しない応答をHTML扱いされる)のリスクになります。対策としてX-Content-Type-Options: nosniffヘッダを返してSniffingを無効化するのが現代のベストプラクティスです。ファイルアップロード用のmultipart/form-dataではboundaryパラメータが各パートの区切りに使われ、サーバ側はこれを使って各ファイルやフィールドを分離します。クライアントはAcceptヘッダで受け取り可能なContent-Typeを列挙でき、サーバは複数形式の中から最適なものを選んで返す「コンテンツ交渉(Content Negotiation)」もこのヘッダと連動して動きます。

Content-Type vs ファイル拡張子 vs 内容判定

Content-Type vs ファイル拡張子 vs 内容判定

Web以外の世界では、ファイル種別の判定にファイル拡張子(.html、.png、.pdf)を使うことが多いですが、HTTP通信では拡張子に頼らずContent-Typeで明示するのが基本です。URLに拡張子が含まれていないAPI(/api/users/123)でも明確に種別を伝えられ、また同じURLが交渉によって異なる形式を返す場合にも正しく動きます。「Magic Number」(バイナリの先頭数バイトでファイル種別を判定する方法)はファイル単体での判定としては確実ですが、毎回読み取るコストがかかり、HTTP通信のような大量・高速処理には不向きです。

ブラウザのMIME Sniffingは「Content-Typeが間違っていても良きに計らう」便利機能でしたが、セキュリティリスクを生むためX-Content-Type-Options: nosniffで無効化することが推奨されています。Content-Lengthはボディのバイト数を表す別のヘッダで、Content-Typeとは役割が異なります。Content-Typeは「データの種類」、Content-Lengthは「データのサイズ」を表す独立した情報です。プロトコル標準のヘッダで明示することで、ブラウザ・CDN・プロキシ・APIゲートウェイなど全レイヤーが種別を確実に理解できる、これがHTTPでのContent-Typeの最大の価値です。

まとめ

Content-TypeはRFC 1341(1992年)由来のMIMEタイプを運ぶHTTPヘッダで、現在はRFC 9110(2022年)で定義されています。type/subtype形式にcharsetなどのパラメータを加え、IANAが2000種超を登録管理する標準化された種別表現です。application/json・text/html; charset=UTF-8・X-Content-Type-Options: nosniffなどの組み合わせで安全・確実にデータ種別を伝え、Web上のあらゆる通信の自己紹介を担う基盤ヘッダとして機能しています。

※本記事はIT用語辞典の手書きドラフトです。公開前に最新情報・出典を確認のうえ加筆修正してください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次