DESIGN / CODE / INFRA / AI

解説

no-cacheとno-storeは同じではない:保存と再検証をHTTPヘッダーで分けよう

no-cacheは使う前の確認、no-storeは保存の制限。小さなローカルHTTPサーバーで、ETagと304の応答を確かめる練習を用意したよ。

no-cacheとno-storeは同じではない:保存と再検証をHTTPヘッダーで分けよう

「キャッシュしないつもり」でno-cacheを付けたのに、保存の可能性があると聞いて戸惑ったことはないかな。Cache-Controlのno-cacheとno-storeは、名前が似ていても同じ指定ではないよ。

今回は、HTTPの応答ヘッダーを読む基本が分かる人向け。Python 3とcurlを使うローカルの練習例で、保存の制御と再検証を分けて確認する。公開サーバーの設定は変更しない。

no-cacheは、再利用の前に検証する

no-cacheは、応答を保存できないという意味ではない。保存した応答を再利用する際に、元のサーバーなどへ検証することを求める指定だよ。

たとえば、ETagという表現の識別子を使い、保存したものと変わっていないかを問い合わせる方法がある。条件が合えば、サーバーは304 Not Modifiedを返せる。304の応答には、通常の200のような本文を付けない。

no-storeは、保存しないことを求める

no-storeは、キャッシュへ保存しないことを求める指定。no-cacheと同じ意味で交換しないようにしよう。

ただし、HTTPSの代わりや、すでに保存されたデータをすべて消す命令ではない。どの情報を、どの経路へ配信しているかも別に確認する必要があるよ。

ローカルサーバーでヘッダーを読む

練習用サーバーを保存し、ターミナルで実行する。127.0.0.1の8765番ポートだけで待ち受ける。すでに使われている場合は、既存の処理を止めずに、作例のポートを別の空き番号へ変更してね。

python3 cache_server.py

別のターミナルから、次を実行する。

curl -i http://127.0.0.1:8765/revalidate
curl -i -H 'If-None-Match: "practice-v1"' http://127.0.0.1:8765/revalidate
curl -i http://127.0.0.1:8765/private

期待する主な結果は次のとおり。

リクエスト 応答の要点
revalidateへ通常取得 200、Cache-Control: no-cache、ETag
同じETagで条件付き取得 304、本文なし
privateへ通常取得 200、Cache-Control: no-store

編集部では、この三つのHTTP応答を確認した。curlの例では、条件付きヘッダーを手動で送っている。ブラウザのキャッシュ全体や、特定CDNの動作を再現したテストではないよ。作業が終わったら、サーバーを起動したターミナルでCtrl+Cを押して終了できる。

304になれば、どのデータも同じとは限らない

作例は固定の本文に固定のETagを付ける、最小の練習用サーバー。実際のサービスでは、内容が変われば識別子も適切に変える必要がある。常に同じETagを返す実装を、そのまま本番へ持ち込まないでね。

また、認証に関係する応答、共有キャッシュ、ほかのCache-Control指示、プロキシなどによっても考慮する条件は変わる。今回の二語だけで、サイト全体のキャッシュ設計が完成するわけではないよ。

設定を変える前には、現在の応答ヘッダーと、どの情報を扱うページかを記録しよう。通信の保護そのものは、HTTPSと証明書の基礎で別に整理できるよ。

参考・出典

みんなのコメント 0

感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。

最初のコメントをどうぞ。