【実務・中級編】HEADメソッドの役割 – HTTPプロトコル・通信規格実践ガイド

レスポンスボディは不要!HEADメソッドでWebリソースの”気配”を掴む方法

Web開発やインフラ運用に携わる皆さん、こんにちは。現場で数々のネットワーク障害と格闘してきたベテランエンジニアです。今日は、HTTPのちょっと地味だけど、知っておくと「なるほど、こういう時に使うのか!」と膝を打つことになる「HEADメソッド」について、皆さんと一緒に深掘りしていきましょう。

HEADメソッドとは? HTTP/1.0からの隠れた功労者

HTTP/0.9の時代は、クライアントがリソースを要求すると、サーバーは必ずそのリソースの「本体」であるレスポンスボディを返していました。しかし、Webが進化するにつれて、リソースの本体ではなく、そのメタデータ(情報についての情報)だけを知りたいというニーズが出てきました。例えば、「このファイル、本当に存在するの?」「最後に更新されたのはいつ?」といった具合です。

そこで登場したのが、HEADメソッドです。GETメソッドとほぼ同じようにリクエストを送信しますが、サーバーはリソースの本体(レスポンスボディ)を返さずに、ヘッダー情報だけを返します。これによって、クライアントはネットワーク帯域を無駄に消費することなく、必要な情報を素早く取得できるようになったのです。HTTP/1.0で正式に定義され、HTTP/1.1でも引き続き重要な役割を担っています。

なぜHEADメソッドが便利なのか? 実務での活用シーン

HEADメソッドの真価は、その効率性にあります。具体的にどのような場面で役立つのか、いくつか例を挙げてみましょう。

  • リソースの存在確認:
  • 「このURLのファイル、本当に存在しますか?」という確認をしたい場合。HEADリクエストを送り、ステータスコードが `200 OK` であれば存在します。`404 Not Found` であれば存在しません。
  • 大量のURLリストをチェックする際に、GETリクエストを全て実行すると、存在しないファイルにもかかわらず、不要なレスポンスボディをダウンロードしてしまうことになり、非常に非効率です。HEADメソッドなら、その無駄が省けます。
  • 最終更新日時のチェック:
  • 「このファイル、前回アクセスしてから更新されていますか?」という場合に、`Last-Modified` ヘッダーを確認できます。もし更新されていれば、改めてGETリクエストで最新の内容を取得すれば良いのです。これは、キャッシュ制御において非常に重要な役割を果たします。
  • リソースのサイズ確認:
  • `Content-Length` ヘッダーを確認することで、リソースのサイズを知ることができます。例えば、ダウンロード前にファイルサイズを確認したり、ネットワーク帯域の目安にしたりするのに役立ちます。
  • Content-Typeの確認:
  • `Content-Type` ヘッダーを確認すれば、そのリソースがどのような形式(HTML、JSON、画像など)なのかを事前に把握できます。これにより、クライアント側で適切な処理を準備することができます。

通信フロー(シーケンス)を見てみよう

HEADメソッドの通信フローは、GETメソッドとほとんど変わりません。違いは、サーバーがレスポンスボディを返さないという点だけです。

sequenceDiagram
participant Client
participant Server

Client->>Server: HEAD /path/to/resource HTTP/1.1
Note right of Client: リソースのヘッダー情報のみを要求
Server–>>Client: HTTP/1.1 200 OK
Note right of Server: レスポンスボディは返さず、ヘッダー情報のみを返す
Server->>Server: Content-Type: text/html
Server->>Server: Content-Length: 1234
Server->>Server: Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
Server->>Server: (その他のヘッダー情報)

1. クライアントが、`HEAD` メソッドを指定して、特定のパス(`/path/to/resource`)のリソースを要求します。
2. サーバーは、そのリソースが存在し、リクエストが有効であれば、`200 OK` のステータスコードと共に、リソースに関連するヘッダー情報(`Content-Type`、`Content-Length`、`Last-Modified` など)を返します。
3. サーバーは、リソースの本体(レスポンスボディ)を一切返しません。

もしリソースが存在しない場合は、`404 Not Found` のステータスコードが返されます。その他のエラー(権限がないなど)であれば、`401 Unauthorized` や `403 Forbidden` など、適切なステータスコードが返されます。

実践! HEADメソッドを使ってみよう

では、実際にHEADメソッドをどのように使うのか、いくつかのツールやコード例を見ていきましょう。

1. `curl` コマンドでの利用

`curl` は、コマンドラインからHTTPリクエストを送信するための強力なツールです。HEADメソッドを使うには、`-I` オプション(または `–head`)を指定します。

指定したURLのヘッダー情報を取得する
curl -I https://www.example.com/

実行例と出力例
$ curl -I https://www.example.com/
HTTP/1.1 200 OK
Content-Encoding: gzip
Accept-Ranges: bytes
Age: 428683
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Tue, 23 May 2023 10:00:00 GMT
Etag: “3147526947+gzip”
Expires: Tue, 30 May 2023 10:00:00 GMT
Last-Modified: Thu, 17 Nov 2016 07:48:10 GMT
Server: ECS (dcb/7EA2)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 648

この出力から、`https://www.example.com/` は存在し(`200 OK`)、HTML形式(`Content-Type: text/html`)であることがわかります。また、最終更新日時(`Last-Modified`)や、キャッシュの有効期限(`Expires`)なども確認できます。

2. JavaScript (Fetch API) での利用

WebブラウザのJavaScriptからHEADメソッドを利用する場合も、Fetch APIを使えば簡単です。`method` プロパティに `’HEAD’` を指定します。

async function checkResource(url) {
try {
const response = await fetch(url, {
method: ‘HEAD’, // HEADメソッドを指定
// mode: ‘no-cors’ // 必要に応じて CORS設定を調整
});

if (response.ok) { // ステータスコードが 200-299 の場合
console.log(`リソース “${url}” は存在します。`);
console.log(`Content-Type: ${response.headers.get(‘Content-Type’)}`);
console.log(`Content-Length: ${response.headers.get(‘Content-Length’)}`);
console.log(`Last-Modified: ${response.headers.get(‘Last-Modified’)}`);
} else {
console.error(`リソース “${url}” の取得に失敗しました。ステータス: ${response.status}`);
}
} catch (error) {
console.error(`ネットワークエラーが発生しました: ${error}`);
}
}

// 使用例
checkResource(‘https://www.example.com/’);
checkResource(‘https://www.example.com/nonexistent-page.html’); // 存在しないページを試す

このコードでは、`fetch` 関数に `method: ‘HEAD’` を渡すことでHEADリクエストを送信しています。`response.ok` でステータスコードを確認し、`response.headers.get()` で必要なヘッダー情報を取得しています。

注意点: ブラウザのJavaScriptから外部ドメインに対してHEADリクエストを送信する場合、CORS(Cross-Origin Resource Sharing)ポリシーの影響を受けることがあります。サーバー側で適切なCORSヘッダー(`Access-Control-Allow-Origin` など)が設定されていないと、リクエストがブロックされる可能性があります。必要に応じて `mode: ‘no-cors’` を試すこともありますが、このモードではレスポンスボディだけでなく、ステータスコードやヘッダー情報も取得できなくなるため、HEADメソッドの利便性が損なわれる場合があります。

3. Python (`requests` ライブラリ) での利用

PythonでWeb APIを扱う際によく使われる `requests` ライブラリでも、HEADメソッドは簡単に利用できます。

import requests

def check_resource_with_head(url):
try:
# HEADメソッドでリクエストを送信
response = requests.head(url)

# ステータスコードを確認
if response.status_code == 200:
print(f”リソース ‘{url}’ は存在します。”)
# ヘッダー情報を取得
print(f”Content-Type: {response.headers.get(‘Content-Type’)}”)
print(f”Content-Length: {response.headers.get(‘Content-Length’)}”)
print(f”Last-Modified: {response.headers.get(‘Last-Modified’)}”)
else:
print(f”リソース ‘{url}’ の取得に失敗しました。ステータスコード: {response.status_code}”)

except requests.exceptions.RequestException as e:
print(f”ネットワークエラーが発生しました: {e}”)

使用例
url_exists = “https://www.example.com/”
url_not_exists = “https://www.example.com/this-page-does-not-exist”

print(f”— Checking: {url_exists} —“)
check_resource_with_head(url_exists)

print(f”\n— Checking: {url_not_exists} —“)
check_resource_with_head(url_not_exists)

`requests.head(url)` を使うだけで、HEADリクエストが送信されます。`response.status_code` でステータスを確認し、`response.headers.get()` でヘッダー情報を取得できます。

HEADメソッドとWeb API設計・インフラ運用における考慮事項

HEADメソッドは便利ですが、その利用にあたってはいくつか考慮すべき点があります。

  • サーバー側の実装:
  • すべてのWebサーバーがHEADメソッドに正しく応答するとは限りません。特に、古いWebサーバーや、カスタム設定が施されたサーバーでは、HEADリクエストをGETリクエストとして誤って処理したり、予期しない応答を返したりする可能性があります。
  • HEADリクエストを処理する際も、GETリクエストと同様に、リソースの存在確認、権限チェック、キャッシュ制御などのロジックを適切に実行する必要があります。
  • パフォーマンスへの影響:
  • HEADメソッドはGETメソッドよりも軽量ですが、それでもサーバー側でリソースのメタデータを生成・検索する処理は発生します。大量のHEADリクエストを短時間に集中させると、サーバーに負荷がかかる可能性があります。
  • 特に、動的に生成されるリソース(データベースから取得した情報など)の場合、HEADリクエストでもその都度データベースクエリが発生することがあります。このような場合は、キャッシュ戦略を工夫するなど、パフォーマンスへの影響を最小限に抑える設計が重要です。
  • 「存在確認」の落とし穴:
  • HEADメソッドで `200 OK` が返ってきたからといって、そのリソースが「常に」利用可能であるとは限りません。リソースは一時的に利用できなくなることもあります。
  • また、認証や認可が必要なリソースの場合、HEADリクエストだけでは「存在」が確認できても、実際のコンテンツへのアクセス権があるかどうかは、GETリクエストを送信してみないと分からない場合があります。(ただし、`401 Unauthorized` や `403 Forbidden` が返ってくれば、アクセス権がないことはわかります。)

まとめ

HEADメソッドは、Webリソースの「気配」を掴むための非常に効率的な手段です。レスポンスボディをダウンロードせずに、リソースの存在、更新日時、サイズ、種類といったメタ情報を素早く取得できるため、Web APIの設計やインフラの運用監視において、帯域幅の節約やパフォーマンス向上に大きく貢献します。

`curl` コマンド、JavaScriptのFetch API、Pythonのrequestsライブラリなど、様々なツールや言語から簡単に利用できますので、ぜひ皆さんの実務で活用してみてください。ただし、サーバー側の実装やパフォーマンスへの影響といった考慮事項も忘れずに、賢く使いこなしていきましょう。

現場で役立つTipsはまだまだたくさんあります。また次の機会にお話しできるのを楽しみにしています!

コメント

タイトルとURLをコピーしました