コンテントネゴシエーションとは

一つのリクエストの中でサーバーとクライアントがお互いのベストな設定を模索する仕組みを「コンテントネゴシエーション」と言います。 基本的には「クライアントが(OOが欲しい)と言う要求を出し サーバーがそれに応える」」と言う方式でネゴシエーションを行います。

例:同じ /resource に対して HTML / JSON / XML などが用意されていて、クライアントの希望やサーバーの方針で最適なものが返される。

対応するリクエストヘッダ

クライアントが希望を伝えるための HTTP ヘッダは、Accept~~~で始まる。

ヘッダ 説明
Accept MIMEタイプ(メディアタイプ)の希望 Accept: text/html, application/json;q=0.9
Accept-Language 言語の希望 Accept-Language: ja, en;q=0.8
Accept-Charset 文字セットの希望 Accept-Charset: utf-8, iso-8859-1;q=0.5 (ほぼほぼutf-8で統一されているため、不要)
Accept-Encoding 転送エンコーディング(圧縮方式など)の希望 Accept-Encoding: gzip, br

ファイルの種類の決定 : Acceptヘッダー

クライアントは 必要なファイル形式を、 MIME タイプで伝えます。 サーバーは提案のうちの一つを選択し、それを使用してクライアントに Content-Type レスポンスヘッダーで選択を伝えます。

  • MINEタイプ
    • text/plain
    • text/html , text/javascript
    • application/json , application/octet-stream(EXEファイルなどの実行ファイル)
    • image/jpeg , image/gif
    • application/vnd.openxmlformats-officedocument.spreadsheetml.sheet (excel) , application/vnd.openxmlformats-officedocument.presentationml.presentation (powerpoint) , application/vnd.openxmlformats-officedocument.wordprocessingml.document (word)

構文は以下の通り

Accept: <MIME_type>/<MIME_subtype>
Accept: <MIME_type>/*
Accept: */*

具体例

  • Accept: text/html : 通常の HTML 文書を受け取りたい
  • Accept: image/* : 画像( image/ で始まる MIME タイプ)なら種類問わず受け取れる
    • image/png、image/jpeg、image/gif などをまとめて指定
  • Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8
    • 以下の優先順位でリクエストする
      • text/html, application/xhtml+xml (最優先, q=1.0)
      • application/xml (優先度 q=0.9)
      • その他すべて (最低, q=0.8)

Accept-Language

クライアント(ブラウザなど)が「どの言語のコンテンツを優先的に欲しいか」をサーバに伝えるために使われます。

  • Web サイトの 多言語対応(日本語ページか英語ページを返すかなど)。
  • API のレスポンス言語切り替え(エラーメッセージやデータ表記をローカライズ)。
  • ブラウザは通常、OSの言語設定やユーザ設定に基づいて自動で送る。

基本の仕組み

  • 書式は Accept-Language: <言語タグ>[;q=<優先度>]
  • 言語タグは BCP 47 という規格に準拠(例: en-USja-JPfr)。
  • q 値(Quality 値)は 優先順位 を示す(0.0~1.0)。省略時は 1.0 =最優先。

例1: 単純指定

Accept-Language: ja

「日本語のコンテンツをください」

例2: 複数指定

Accept-Language: ja,en

「日本語が欲しいけど、なければ英語でもOK」

例3: 優先度付き

Accept-Language: ja-JP, en-US;q=0.8, en;q=0.7
  • ja-JP(日本語・日本地域)を最優先
  • en-USアメリカ英語)を次に優先(q=0.8)
  • en(英語全般)を最後に優先(q=0.7)

Accept-Encoding

クライアント(ブラウザや curl など)が「どんな圧縮形式(エンコーディング方式)なら受け取れるか」をサーバに伝える

  • 書式は Accept-Encoding: <エンコーディング>[;q=<優先度>]
  • 主に レスポンスの転送サイズを小さくするための圧縮方式をやりとりする。
  • サーバは Accept-Encoding を参考にして、Content-Encoding ヘッダーを付けてレスポンスを返す。

よく使われる値

  • gzip → 最も一般的。広くサポート。
  • deflate → zlibベースの圧縮。あまり使われない。
  • br → Brotli圧縮。最近のブラウザはよく使う。gzip より効率が良い場合が多い。
  • zstd → Zstandard。比較的新しい方式で超高速・高圧縮率。
  • identity → 圧縮なし(デフォルト)。

例1: 単純指定

Accept-Encoding: gzip

gzip圧縮されたレスポンスなら受け取れる」

例2: 複数指定

Accept-Encoding: gzip, deflate, br

gzip、deflate、Brotli どれでもOK」

例3: 優先度付き

Accept-Encoding: br;q=1.0, gzip;q=0.8, *;q=0.1
  • br を最優先(q=1.0)
  • gzip も対応できる(q=0.8)
  • その他の形式は低優先度(q=0.1)

👉 サーバは Brotli が使えればそれを返す。なければ gzip、それもなければ他の方式。

ちなみに、identity;q=0 とすると「圧縮なしは絶対に受け付けない」という意味になる。

サーバからの応答例

1.クライアントが以下のコーディングで送信

Accept-Encoding: gzip, br

2.サーバが以下の内容で返答

Content-Encoding: br

サーバは Brotli で圧縮して返したことを明示している。

代表的なサーバ/フレームワーク

以下は、圧縮/ Accept-Encoding に対応している/対応可能なものと、それがどの程度デフォルトか、あるいは設定が必要か、の情報です。

サーバ/フレームワーク 圧縮対応の状態 備考
nginx 非常に一般的に対応。gzip は標準モジュールに含まれる。Brotli はモジュール(追加)で対応可能。 gzip on; など設定が必要。Brotli は ngx_brotli モジュールなどで。 Wikipedia+2PixelFreeStudio Blog -+2
Apache HTTP Server mod_deflate や mod_brotli を使って対応可能。 Brotli は古くから含まれてないが、モジュール追加で対応。 Wikipedia+1
IIS gzip など標準である程度サポートあり。Brotli は近年のバージョンで対応追加。 Stack Overflow+1
Caddy よく圧縮がデフォルトで有効化されていたり、設定が簡単。たとえば encode gzipencode zstd gzip のようなディレクティブで。 DebugBear
CDN/プロキシサーバ(Cloudflare, Amazon CloudFront 等) 多くの場合、自動で圧縮を行う設定がある。クライアントの Accept-Encoding を見て gzip や Brotli を適用。 The Cloudflare Blog+2Wikipedia+2
Node.js + Express デフォルトでは圧縮ミドルウェアを使う必要あり。自分で compression() を使う。デフォルトで圧縮がオンというわけではない。 Express+2Medium+2
NestJS Express や Fastify アダプターを使っており、圧縮ミドルウェア(Express の圧縮 or Fastify の compress プラグイン)を導入できる。デフォルトで「圧縮ミドルウェアを組み込む」設定になっている場合がある/簡単。 NestJS Documentation
Ruby on Rails Rails 本体にはデフォルトで gzip 圧縮ミドルウェアはあまり「有効」にしていないことが多い。Rack::Deflater を使えば対応可能。デフォルトで有効ではない。 Stack Overflow+1
その他 (Tomcat, Jetty, etc.) 多くの Java サーブレットコンテナはフィルターなどで gzip を提供できる。標準配布に含まれていたり設定次第。

page:https://minegishirei.hatenablog.com/entry/2025/09/20/080350