Content-Typeは、クライアントとサーバー間で転送されるデータの形式を指定するHTTPヘッダーです。正しいMIMEタイプがないと、ブラウザはレスポンスを正しく処理できません。テキストファイルは生のコードとして表示され、画像は開きません。MDN Web Docs、2025によると、Content-TypeはHTTPプロトコルにおけるあらゆるタイプのデータの正しい転送に必須であり、受信者がメッセージ本文をどのように解釈するかを決定します。
重要ポイント
Content-Typeは、表現ヘッダーのグループに属するHTTPヘッダーで、メッセージ本文のデータ形式を受信者に伝えます。本文を含むHTTPリクエストとレスポンスには必須であり、これがないとクライアントは受信したバイトを正しく解釈できません。Content-Typeに基づいて、ブラウザまたはモバイルアプリはパーサーを選択します。text/htmlの場合はHTMLエンジンを起動し、image/pngの場合はPNGデコーダーを、application/jsonの場合はJSONパーサーを起動します。
Content-Typeの値はMIMEタイプです。これはデータ形式の標準化された識別子です。MIMEはMultipurpose Internet Mail Extensionsの略で、この標準は元々電子メールの添付ファイル用に作られました。しかし、HTTPの基盤となり、現在ではウェブページの転送からREST APIでのデータ交換まで、あらゆる場所で使用されています。各MIMEタイプは、スラッシュで区切られたメインカテゴリと修飾サブタイプの2つの部分で構成されています。
charsetパラメータはテキスト形式のContent-Typeを補完します。例えば、Content-Type: text/html; charset=utf-8は、UTF-8エンコーディングでHTMLドキュメントが転送されていることを示します。IETF RFC 7231のセクション3.1.1.5によると、Content-Typeヘッダーは本文を含むHTTPメッセージに必須であり、これがない場合はapplication/octet-streamとして扱われるか、MIMEスニッフィングが発生します。
1991年にリリースされたHTTP/0.9プロトコルはHTMLページのみを転送していたため、データタイプはデフォルトで暗黙的に決まっていました。RFC 1945でHTTP/1.0が導入されると、開発者たちは画像、スタイルシート、スクリプトを転送する必要性を認識しました。彼らは電子メールプロトコルからMIME標準を適応させ、Content-TypeはHTTPの不可欠な部分となりました。それ以来、IANAレジストリは数百の値に拡大しました。おなじみのtext/htmlから、最新のimage/avifやapplication/manifest+jsonまでです。
Content-Typeは攻撃からの保護において重要な役割を果たします。サーバーがtext/plainのMIMEタイプでHTMLファイルを送信する場合、ブラウザはJavaScriptを実行したりDOMを構築したりしません。これによりXSS攻撃を防ぎます。OWASPが推奨するX-Content-Type-Options: nosniffヘッダーは、ブラウザがコンテンツに基づいてMIMEタイプを推測することを完全に禁止します。PortSwigger Researchによると、MIMEスニッフィング攻撃は特にInternet Explorer 6〜9で蔓延しており、ブラウザがContent-Typeを無視してファイルの最初のバイトからタイプを判断していました。
MIMEタイプはtype/subtype形式で指定されます。typeはデータの一般的なカテゴリで、subtypeはその中の特定の形式です。例えば、image/pngの場合、カテゴリimageは画像を示し、サブタイプpngはPortable Network Graphics形式を指定します。カテゴリはtext、image、audio、video、application、multipart、messageのわずかしかありません。残りの多様性はサブタイプからもたらされ、その数は数百に及びます。
追加パラメータはサブタイプの後にセミコロンで渡されます。最も一般的なパラメータはエンコーディングを指定するcharsetです。Content-Type: application/json; charset=utf-8は、UTF-8エンコーディングでJSONドキュメントが転送されていることを示します。形式的には、RFC 8259に従いJSONは常にUTF-8であるため、application/jsonのcharsetは冗長ですが、明示的な指定は古いHTTPクライアントとの互換性を向上させます。
| カテゴリ | サブタイプの例 | 説明 |
|---|---|---|
| text | html, plain, css, javascript, csv | 人間が読めるテキスト形式 |
| image | jpeg, png, gif, webp, svg+xml, avif | ラスター画像とベクター画像 |
| audio | mpeg, ogg, wav, mp4, webm | ストリーミング再生用のオーディオ形式 |
| video | mp4, webm, ogg, x-msvideo, 3gpp | ビデオ形式とマルチメディアコンテナ |
| application | json, xml, pdf, zip, octet-stream, protobuf | バイナリデータと構造化データ |
| multipart | form-data, mixed, alternative, byteranges | 複数の部分からなる複合ドキュメント |
標準MIMEタイプはIANAレジストリに登録されており、メインカテゴリのプレフィックスを持ちます。非標準(ベンダー固有)タイプはx-プレフィックスまたはvnd.company.type形式を使用します。例:GoogleのKML形式の場合はapplication/vnd.google-earth.kml+xml。ブラウザは非標準タイプを認識できない場合があるため、不明な添付ファイルにはapplication/octet-streamが使用されます。これは、ブラウザが表示を試みず、ファイルとしてダウンロードするよう促すユニバーサルバイナリストリームです。
charsetパラメータはテキストの正しい表示に重要です。これがないと、ブラウザが文字を誤って解釈し、文字化け(mojibake)が発生する可能性があります。ウェブの標準はUTF-8ですが、西ヨーロッパ言語用のISO-8859-1(Latin-1)や古いサイトのキリル文字用のwindows-1251も見られます。W3Cの推奨は、text/htmlとtext/plainには常にcharset=utf-8を指定することです。application/jsonにはcharsetは必要ありません。
実際には、ウェブ開発者とモバイル開発者は限られたMIMEタイプのセットを扱います。これらのタイプを知ることは、サーバーの正しい設定、HTTPクライアントの作成、静的ファイルの処理に不可欠です。text/htmlはウェブページの主要なタイプで、ApacheやNginxサーバーがHTMLファイルに対してデフォルトで返します。application/xhtml+xmlはあまり使用されず、XHTMLドキュメントにのみ使用されます。
application/jsonはREST APIの標準になりました。サーバーはこのMIMEタイプでJSONデータを返し、クライアントはPOSTおよびPUTリクエストでそれを送信します。text/javascript(非推奨)とapplication/javascriptはJavaScriptファイルに使用されます。W3Techs Survey、2025によると、JSONはウェブ上で最も急速に成長しているデータ形式であり、2018年にXMLを追い越しました。SOAPサービスでは、今でもtext/xmlまたはapplication/soap+xmlが使用されています。
画像の場合、MIMEタイプはファイル形式によって決まります。JPEGの場合はimage/jpeg、PNGの場合はimage/png、GIFの場合はimage/gif、最新のWebP形式の場合はimage/webpです。image/svg+xmlはベクターグラフィックスに使用され、埋め込みスタイルとスクリプトをサポートしています。video/mp4、audio/mpeg、application/pdfは他によく見られるタイプです。ウェブフォントにはfont/woff2、font/woff、font/ttfが使用されます。
HTMLフォームを介してファイルをアップロードする場合、multipart/form-dataが使用されます。これはリクエストを複数の部分に分割する複合MIMEタイプです。各部分には独自のContent-Typeヘッダーと、フィールド名と元のファイル名を指定するContent-Dispositionがあります。サーバーはブラウザが決定した実際のMIMEタイプでファイルを受け取り、バックエンド側でそれを検証できます。application/octet-streamは不明なタイプのファイルに使用されます。ブラウザはコンテンツの表示を試みず、ディスクに保存するよう促します。
MIMEタイプはCDNとブラウザのキャッシュポリシーに影響します。安定したURLを持つ画像は通常、長期間(1年以上)キャッシュされますが、HTMLページは数分または数秒間キャッシュされます。CDNサーバー(CloudflareやAkamaiなど)は、Content-Typeを使用して圧縮アルゴリズムを選択します。text/*はgzipまたはbrotliで圧縮されますが、画像はすでに圧縮されているためimage/*は圧縮されません。サーバーでの正しいContent-Type設定は、ウェブページやモバイルアプリケーションの読み込みパフォーマンスに直接影響します。
サーバーは、要求されたファイルのタイプまたは動的に生成されたコンテンツに基づいて、HTTPレスポンスにContent-Typeヘッダーを設定します。NginxやApacheなどの一般的なウェブサーバーには、ファイル拡張子を対応するContent-Typeにマッピングする組み込みのMIMEタイプテーブルがあります。例えば、index.htmlはtext/htmlを取得し、style.cssはtext/cssを取得します。動的レスポンスの場合、開発者はPHP、Python、Java、KotlinなどのアプリケーションコードでContent-Typeを設定します。
クライアントはContent-Typeを使用してハンドラを選択します。サーバーがtext/htmlを返す場合、ブラウザはHTMLパーサーを起動してDOMツリーを構築します。image/pngの場合はPNGデコーダーを起動します。Content-Typeがないか間違っている場合、クライアントはMIMEスニッフィングを適用します。ファイルの先頭のシグネチャ(マジックバイト)でタイプを推測しようとします。JPEGはバイトFF D8 FFで始まり、PNGは89 50 4E 47で、PDFは25 50 44 46で始まります。このプロセスは潜在的に危険であり、X-Content-Type-Options: nosniffヘッダーによって無効にされます。
モバイルアプリケーションでは、Content-TypeはHTTPクライアントによって処理されます。AndroidのOkHttpは、レスポンスからContent-Typeヘッダーを自動的に解析し、Response.header("Content-Type")メソッドで提供します。iOSのURLSessionクライアントは、URLResponse.mimeTypeプロパティを通じて同じことを行います。両方のプラットフォームで、Content-Typeはパーサーの選択に使用されます。JSONの場合はAndroidではMoshiやGson、iOSではCodable、画像の場合はGlide、Coil、SDWebImageなどです。
コンテンツネゴシエーションは、クライアントがAcceptヘッダーで希望するレスポンス形式を指定し、サーバーが適切な形式を選択して対応するContent-Typeで返すHTTPメカニズムです。例えば、クライアントがAccept: application/jsonを送信すると、サーバーはContent-Type: application/jsonで応答します。サーバーが要求された形式を提供できない場合は、406 Not Acceptableを返します。REST APIでは、このメカニズムにより単一のエンドポイントがJSON、XML、HTMLでデータを返すことができます。
Content-TypeヘッダーはHTTPリクエストとHTTPレスポンスの両方で使用されます。リクエストでは、リクエスト本文の形式を指定します(例:POSTでJSONを送信する場合)。レスポンスでは、返されるデータの形式を指定します。主な違いは、リクエストのContent-Typeはクライアントが設定し、レスポンスのContent-Typeはサーバーが設定することです。リクエストでContent-Typeを誤って設定すると、サーバーが本文を解析できなくなり、400 Bad Requestまたは415 Unsupported Media Typeエラーが返されます。
HTTPリクエストでは、リクエストに本文が含まれる場合、Content-TypeはPOST、PUT、PATCHメソッドに必須です。GET、HEAD、DELETEは通常本文を使用しないため、Content-Typeは指定されないか無視されます。enctype="multipart/form-data"属性を持つHTMLフォームを送信する場合、ブラウザは自動的にContent-Type: multipart/form-dataを一意の境界文字列とともに設定し、複合リクエストの各部分を区切ります。各部分は--boundaryで区切られ、リクエストの終わりは--boundary--で示されます。
HTTPレスポンスでは、Content-Typeはサーバーによって設定されます。サーバーがContent-Typeを指定しない場合、クライアントはMIMEスニッフィングを有効にするか、レスポンスをapplication/octet-streamとして処理します。HTTP HEADメソッドを使用すると、本文を転送せずにContent-Typeを含むレスポンスヘッダーを取得できます。これは、リソースを完全に読み込む前にそのタイプを確認するのに便利です。CDNサーバーはコンテンツを変換する際にContent-Typeを上書きすることがあります(例:画像をWebPに変換する場合)。
import okhttp3.*
fun checkContentType() {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://api.example.com/resource")
.head()
.build()
client.newCall(request).execute().use { response ->
val contentType = response.header("Content-Type")
val mediaType = MediaType.parse(contentType)
println("タイプ: ${mediaType?.type}, サブタイプ: ${mediaType?.subtype}")
}
}
モバイル開発では、Content-TypeヘッダーはHTTPクライアントによって自動的に処理されます。AndroidのOkHttpでは、Content-TypeはRequestBodyを介して設定されます。val body = "{}".toRequestBody("application/json".toMediaType())。Retrofitはアノテーションを通じてContent-Typeを管理します。JSONの場合は@Body、マルチパートの場合は@Partです。iOSでは、URLSessionがHTTPBodyのContent-Typeを設定し、Alamofireはencodingパラメータ(JSONEncoding.defaultやURLEncoding.default)を介してこれを行います。手動でのContent-Type設定は、生のソケットやカスタムプロトコルを扱う場合に必要です。
誤ったContent-Typeは、ウェブサービスの開発と統合における最も一般的な問題の1つです。最も頻繁なエラーは、サーバーがapplication/jsonの代わりにtext/htmlを返す場合です。クライアントはJSONをHTML文字列として受信し、解析できずに例外をスローします。これは、ウェブフレームワークがデフォルトでHTML用に設定されており、開発者がAPIエンドポイントのContent-Typeを上書きするのを忘れた場合に発生します。PHPではheader('Content-Type: application/json')がない場合、Spring Bootではproducesアノテーションがない場合に発生します。
2番目に多いエラーはcharsetの誤りまたは欠落です。サーバーがtext/html; charset=iso-8859-1を送信し、ブラウザがUTF-8を期待する場合、キリル文字が文字化け(mojibake)として表示されます。この問題は、UTF-8に移行していない古いサイトに典型的です。JSONの場合、RFC 8259が追加のネゴシエーションなしでUTF-8を規定しているため、このようなエラーはあまり一般的ではありません。解決策は、サーバー設定でテキストMIMEタイプに常に明示的にcharset=utf-8を指定することです。
3番目の問題は、Content-Typeと実際のコンテンツの不一致です。サーバーがContent-Type: image/pngを送信したが、レスポンス本文にWebP画像が含まれている場合、ブラウザはそれをデコードできない可能性があります。CDNサーバーは、形式を変更して画像を圧縮しても、Content-Typeヘッダーを更新しないことがあります。実際のコンテンツに対するContent-Typeの確認は、APIテストとモバイルアプリケーションの統合テストにおいて必須の手順です。
デバッグには、ブラウザの開発者ツール(Networkタブ)、レスポンスヘッダーを確認するための-Iフラグ付きcurl、またはCharles ProxyやWiresharkなどのトラフィックスニッファーを使用します。Nginxはinclude mime.typesディレクティブで設定し、ApacheはAddTypeとAddDefaultCharsetで設定します。静的ファイルの場合は、ファイル拡張子がそのMIMEタイプと一致することを常に確認してください。すべてのプログラミング言語で動的レスポンスを生成する場合は、データを出力する前に明示的にContent-Typeを設定してください。これにより、ほとんどの問題を防ぐことができます。
よくある質問
Content-Typeがない場合、ブラウザはMIMEスニッフィングを有効にします。これは、データタイプを自動的に判断するためにレスポンスの最初のバイトを分析します。これにより、コンテンツの誤った処理やセキュリティの脆弱性が発生する可能性があります。X-Content-Type-Options: nosniffヘッダーを持つ最新のブラウザは、推測を完全にブロックします。
Content-Typeは現在のメッセージ(リクエストまたはレスポンス本文)で転送されるデータの形式を指定します。Acceptは、クライアントがどのレスポンス形式を好むかをサーバーに伝えるリクエストヘッダーです。Content-Typeはデータの送信者によって設定され、Acceptは受信者によって設定され、両者はコンテンツネゴシエーションメカニズムに参加します。
JSONの公式MIMEタイプはRFC 8259に従いapplication/jsonです。以前はtext/x-jsonが使用されていましたが、このタイプは非推奨です。application/jsonにcharsetパラメータは必要ありません。仕様に従い、JSONは常にUTF-8、UTF-16、またはUTF-32エンコーディングで、自動バイトオーダー検出(BOM)付きで転送されるためです。
これは、ウェブフレームワークがAPIエンドポイントのデフォルトのContent-Typeを上書きしない場合に発生します。PHPではheader('Content-Type: application/json')を呼び出して修正し、Spring Bootでは@GetMapping(produces = "application/json")アノテーションで、Express.jsではres.set('Content-Type', 'application/json')メソッドで修正します。
application/octet-streamは、形式が不明なバイナリデータのためのユニバーサルMIMEタイプです。ブラウザはそのようなファイルをウィンドウに表示しようとせず、ディスクに保存するよう促します。ファイルダウンロード、電子メールの添付ファイル、サーバーが転送されるコンテンツの正確なタイプを判断できない場合のストリーミングデータに使用されます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。