理系学生日記

おまえはいつまで学生気分なのか

Varyヘッダとキャッシュについて

さっき Cache-Control ヘッダの話を書いたんですが、もちろんキャッシュ制御に関しては Cache-Control ヘッダだけで収まる話ではなく、他にも多々のヘッダが影響を与えます。 その一つに、Vary ヘッダがあるので、今日はその話でも。

Vary ヘッダ

Vary ヘッダは、RFC7231 で定義されているヘッダです。 vary というと「変わる」という意味を持つ動詞ですが、Vary ヘッダはその名の通り、「どのヘッダによってコンテンツが変わったのか」を示すレスポンスヘッダです。

例えば、よくあるタイプのスマートフォン対応の 1 つとして、User-Agent ヘッダを見て、PC 用 HTML を返却するか、スマフォ用 HTML を返却するかを切り替える実装を良く見ます。 この場合、レスポンスヘッダに Vary: User-Agent ヘッダを付けるのが常套手段です。ちなみにこれ、Google も SEO として推奨してるからな。B2C 系システムつくるときは気をつけろよ(戒め)。

他にも、リクエストヘッダの Accept-Encoding を見てページの言語を切り替えるような場合は、Vary: Accept-Encoding を付けることになります。だいたいイメージ湧いたでしょうか。

Vary ヘッダとキャッシュ

Vary ヘッダとキャッシュの関係性は、上で書いた内容と強く関連します。

キャッシュというのは通常、リクエストメソッドとターゲット URI をキーとしてレスポンスを保存します。 しかし、例えば User-Agent リクエストヘッダで HTML を出し分けるようなシステムの場合、メソッドと URI だけでなく、User-Agent ヘッダの値もキャッシュのキーにしなければ、クライアントに依っては正しいキャッシュを手に入れられなくなるケースがあります。 つまり、Vary レスポンスヘッダは、「キャッシュに対してキャッシュキーの追加を指示する」という意味があります。

Vary ヘッダがなかったらどうなるかというと、わりと悲惨でして。 いや、User-Agent くらいだったら良いんですよ、PC でスマフォサイトが見れたりしちゃうけど。 これがもし、Accept-Encoding とかで起こっちゃうと、こんなかんじになって、レンダリングすらされなくなっちゃいます。

  1. クライアント A から Accept-Encoding: gzip つきのリクエストが送信され、サーバは gzip 圧縮されたコンテンツを返す。これがキャッシュサーバにキャッシュされる。
  2. gzip を理解しないクライアント B が同じ URL にリクエストを発行する (Accept-Encoding ヘッダは含まれていない) と、キャッシュサーバが gzip 圧縮されたキャッシュを返す

このあたりについては、Fastry がベストプラクティスの記事を書いてくれているので、参考にすると良いと思いました。

参考文献