HTTPの応答には、URLを示すヘッダーがいくつもあります。名前の似たLocationとContent-Locationも、同じ役割ではありません。受け取った本文が何を表すのかを調べるときは、「要求した場所」「作成した資源の場所」「この本文に対応する場所」を分けると、応答を読み違えにくくなります。
簡単にまとめると?
- Content-Locationは、メッセージ内の表現に対応する資源を示す情報です。要求先のURIを置き換えるものではありません。
- Locationは、3xx応答では移動先、201応答では新たに作成した主要な資源を指します。ステータスと一緒に読みます。
- 本文が作成結果そのものなのか、処理の受付票なのかで、二つの値が同じ場合と異なる場合があります。要求側のContent-Locationで更新対象を切り替えることはできません。
同じURLでも、何を指す情報なのかを確認する
HTTPでいう資源は、記事や測定データ、処理の受付票など、URIで識別される対象です。その資源の状態を、HTMLやJSONなどのデータと関連情報で伝えるものが「表現」です。ここでは、応答の本文と、その本文が対応する資源の関係に注目します。
RFC 9110のContent-Locationは、そのメッセージの内容に含まれる表現に対応する資源の識別子を示します。応答を作った時点に、そのURIへGETしたなら、200応答で同じ表現が返る、という関係です。[1、§8.7] 将来いつ取得しても同じ内容だという永続的な保証ではありません。
一方、Locationが表す関係は、要求メソッドと応答ステータスの組合せで決まります。201 Createdでは要求によって作成された主要な資源、3xxのリダイレクトでは要求を移す先を示します。[1、§10.2.2] Locationを見ただけで「必ず画面が移動する」と判断せず、まず応答の種類を確かめます。
言語別の表現を返す例
架空の資料サイトで、利用者が/guideを要求し、サーバーが日本語の本文を選んで返す場面を考えます。説明に必要な項目だけを抜き出すと、応答は200 OK、Content-Location: /guide/jaとなります。ここでは、より具体的な日本語版のURIをサーバーが用意している、という前提です。
要求先は引き続き/guideです。Content-Locationの値は、その要求に対して今回選ばれた表現を、より具体的に識別するための情報です。これを受け取ったことだけで、要求先を書き換えたり、リダイレクトを成立させたりするわけではありません。GETやHEADの成功応答で両者が異なる場合について、RFCは内容交渉で選んだ表現の識別子として説明しています。[1、§8.7]
ただし、そのURIが本文と対応するという説明は、送信元の主張です。要求先とContent-Locationが異なる場合、両方の識別子が同じ資源所有者に属しているという信頼が必要で、その所有関係をHTTPだけで機械的に確定できるわけではありません。別のURLが書かれていることを、相手の所有権や内容の正しさの証明として扱わないことが大切です。
201の本文が、新しい資源そのものか、受付票か
次に、架空のAPIへ資料の作成を依頼する例を使います。POST /reportsに対して201 Createdが返り、Location: /reports/42と書かれていれば、作成された主要な資源の場所は/reports/42です。これだけでは、本文がその資料の表現なのか、処理についての説明なのかを同じようには読めません。
さらにContent-Location: /reports/42があり、Locationと同じ値なら、本文は新しく作成した資源の現在の表現だと示されています。[1、§8.7] たとえば、登録後に確定したタイトルや識別子を含む資料のJSONを、そのまま本文で返す設計です。
別の設計では、Locationは/reports/42のまま、Content-Locationを/receipts/9にします。本文は資料そのものではなく、作成処理についての受付票です。その受付票を後でGETする場所として、別のURIを示しています。URIが二つある理由を「どちらかが誤り」と決めず、それぞれが何の表現を指しているのかで比べます。

この違いは、クライアントが応答を保存する際にも役立ちます。資料の状態として扱う本文と、処理履歴として扱う受付票を混ぜると、画面に表示したいものと保存したものがずれるためです。実際の処理では、ステータス、Content-Type、本文の構造、APIの契約も併せて確認します。
PUTの更新先を、ヘッダーで差し替えない
Content-Locationは要求にも付けられます。その場合は、送信する表現を、変更する前にどこから取得したかを伝える情報です。サーバーはこれを一時的な要求の文脈として扱い、要求の意味を変更するために使ってはいけないとされています。[1、§8.7]
たとえばPUT /guideにContent-Location: /guide/jaを付けても、「日本語版だけを更新する要求」へ自動的に読み替えることはできません。要求の対象は/guideです。日本語版という個別の資源をPUTで更新したいなら、サーバーがその操作を提供していることを確認したうえで、/guide/jaを直接の要求先にします。
本文の出所と更新対象を混同しないよう、ログにもメソッドと要求先を残します。Content-Locationだけを取り出して更新先として再利用する処理は、この区別を失います。値の文字列がURIとして妥当であることと、そのURIへ送信する意味や権限が妥当であることは別に点検します。
三つの欄を並べて読む
応答を調べるときは、まず要求先、次にステータスとLocation、最後にContent-Locationと本文を並べます。要求先はどの資源への操作だったか、Locationはその応答でどんな関係を示すか、Content-Locationはどの資源の表現を本文に入れたと説明しているか、という三つの問いに分けます。
今回のURI例はすべて独自に作った説明用のものです。相対参照を同じ架空のオリジンに対して絶対URIへ直す照合は行いましたが、ネットワーク通信やブラウザーの遷移を実測したものではありません。また、Content-Locationがあることだけを理由に保存期間やキャッシュ再利用の可否を決めることも、本稿の例からは導けません。
二つのヘッダーを短い同義語へまとめるよりも、メソッド、ステータス、本文の役割まで一緒に記録する方が、APIの設計や不具合調査で判断を戻しやすくなります。
出典
- IETF / RFC Editor, RFC 9110: HTTP Semantics(2022年6月、STD 97、発行済みInternet Standard)、§8.7 Content-Location、§10.2.2 Location。2026年10月23日取得の同文書を参照。後続文書や正誤表の全件評価ではない。URI例と比較図は独自作成。
