1. ホーム
  2. Web プログラミング
  3. CSS/HTML
  4. 基本チュートリアル

HTTPベースのブラウザキャッシュ機構の網羅的解析

2022-01-19 14:07:40

ブラウザキャッシングとは?

ウェブキャッシュとは、ウェブサーバーとクライアント(ブラウザ)の間に存在するウェブリソース(htmlページ、画像、js、データなど)のコピーのことです。キャッシュは、受信したリクエストに基づいて出力されたコンテンツのコピーを保持する。同じURLで次のリクエストが来たとき、キャッシュはキャッシュの仕組みに基づいて、アクセスリクエストに直接コピーで応答するか、ソースサーバーに別のリクエストを送信するかを決定する。

ブラウザは、一度訪れたウェブページをキャッシュしておき、再びURLアドレスにアクセスしたときに、ページが更新されていなければ、ページを再度ダウンロードせず、ローカルにキャッシュされたページを直接使用するのが一般的です。

ブラウザは、リソースが更新されたことをサイトが明示的に特定した場合にのみ、ページを再ダウンロードします。ブラウザとウェブサーバは、キャッシュ機構に従ってキャッシュされる

非HTTPプロトコルで定義されたキャッシュの仕組み

ブラウザのキャッシュ機構は、実は、主にHTTPプロトコルで定義されたキャッシュ機構(Expires; Cache-controlなど)です。しかし、非 HTTP プロトコル定義のキャッシュ機構もあります。たとえば、ウェブ開発者が HTML ページのノードにタグを追加できる HTML メタタグを使用する方法です。

<meta http-equiv="Pragma" content="no-cache">

上記のコードが行うことは、現在のページがキャッシュされておらず、訪問のたびにサーバから取得する必要があることをブラウザに伝えることです。使い方は簡単ですが、これをサポートできるのは一部のブラウザだけで、プロキシは HTML コンテンツ自体を解析しないので、すべてのキャッシュプロキシサーバはこれをサポートしません。

キャッシュ・フローチャート

ブラウザのキャッシュを活用するためのプロセス。

HTTPキャッシュ機構

レスポンス・ヘッダ内のCache-ControlとExpires属性によると、両方が存在する場合はCache-Controlの方が優先されます。

Cache-Control

<イグ

このフィールドは、ブラウザがサーバーにリクエストを送信せずに直接ローカルキャッシュを使用する際に制御するために使用されます。通常、以下の値を持ちます。

  • Public : レスポンスが任意のバッファにキャッシュ可能であることを示す.
  • Private : 単一ユーザーに対する応答メッセージの全体または一部が共有キャッシュで処理できないことを示す。これにより、他のユーザからのリクエストに対してそのユーザの応答メッセージが無効な場合、その応答メッセージの一部のみを記述することができます。
  • no-cache : リクエストまたはレスポンスメッセージをキャッシュできないことを示します。
  • no-store : 重要な情報が不用意に掲載されるのを防ぐために使用します。リクエストメッセージの中で送ると、リクエストもレスポンスメッセージもキャッシュを使用しないようになります。
  • max-age : ブラウザが指定された時間より長い寿命を受け入れることができることを示す ( 秒単位 ).
  • min-fresh : 現在時刻に指定時刻を加算した時刻よりも短い時刻でレスポンスを受信できることを示す。
  • max-stale : ブラウザがタイムアウト時間を超えて応答メッセージを受信できることを示します。max-stale messageの値が指定された場合、ブラウザはタイムアウト時間の指定値以内のレスポンスメッセージを受信することができる。

Expires (the stone age caching mechanism)

Expiresヘッダーフィールドは、その日付以前のリソースへのすべてのリクエストがサーバーに要求されることなく、ブラウザーを使って直接キャッシュされる日付と時刻を提供します。

例 期限切れです。2009年11月8日(日) 03:37:26 GMT

注意事項

  • cache-control max-age と max-stale は Expires ヘッダを上書きします。
  • Expiresを使用すると、サーバーサイドの時間とブラウザの時間の不一致が発生します。
  • また、Expires は HTTP 1.0 のものだと言う人もいますが、現在、デフォルトのブラウザはすべてデフォルトで HTTP 1.1 を使っています。

キャッシュが期限切れであることをサーバー側が判断する方法

サーバー側は、If-Modified-Since (Last-Modified) 属性と If-None-Match (Etag) 属性の値によって、キャッシュの有効期限が切れているかどうかを判断する。

最終修正時刻/修正後時刻

Last-Modified/If-Modified-Since は、Cache-Control と共に使用されます。

Last-Modified : レスポンスリソースの最終更新時刻です。

If-Modified-Since : キャッシュが失効し、リソースに Last-Modified 宣言があることが判明すると、If-Modified-Since (その値は Last-Modified) がリクエストヘッダに含まれるようになる。サーバーはリクエストを受信し、ヘッダーのIf-Modified-Sinceを見つけると、リクエストされたリソースの最終更新時刻と比較する。最終更新時刻が新しい場合、つまりリソースが再び変更された場合、レスポンスはリソース全体の内容 (レスポンスメッセージパッケージに書かれている) に対して HTTP 200 が返され、最終更新時刻が古い場合、つまりリソースに新しい変更がない場合、レスポンスは HTTP 304 で、ブラウザに保存したキャッシュを使い続けるように指示します。

エタグ/イフ・ノン・マッチ

Etag/If-None-Match は、Cache-Control と共に使用する必要があります。

Etag Apache の ETag の値は、デフォルトでは、ファイルのインデックスノード、サイズ、最終修正時刻 (MTime) のハッシュです。

If-None-Match : キャッシュが失効し、リソースに Etage 宣言があることが判明すると、リクエストは If-None-Match でヘッダライズされます (値は Etag です)。サーバーはリクエストを受け取り、If-None-Match ヘッダを見つけると、リクエストされたリソースの対応するチェックサム文字列と比較し、200 か 304 を返すかどうかを決定します。

Last-Modifiedがあるのに、なぜEtagが必要なのか?

Etagは、主にLast-Modifiedのいくつかの難題を解決するために生まれました。

  • Last-Modifiedのアノテーションは秒単位の精度しかないため、あるファイルが1秒以内に複数回変更された場合、そのファイルがいつ変更されたかを正確にアノテーションすることはできません。
  • 定期的に生成されるファイルの場合、コンテンツは変更されないのにLast-Modifiedが変更され、キャッシュに使用できない場合があります。
  • ファイルが更新された時刻を正確に取得できない場合や、プロキシサーバーと時刻が一致しない場合があります。

200 OK (from cache) と 304 Not Modified の違いについて

200 OK ( from cache ) は、サーバーにリクエストを送信せず、ローカルのキャッシュファイルを直接使用します。304 Not Modified はサーバーにリクエストを行い、サーバーがブラウザのバージョンのキャッシュがまだ利用可能であると考える場合は 304 を返します。

200 OK( from cache ) アクションとともに発生します。

1.アドレスバーでキャリッジリターン

2. ページリンクのジャンプ

3. 前方、後方

304 Not Modifiedの発生アクション。

1. F5リフレッシュ

2. 新しいウィンドウを開く

キャッシュのさまざまなソース

from disk cache : キャッシュされたリソースをディスクから取得し、再ダウンロードせずに次のアクセスを待ち、ディスクから直接取得します。CurlCacheManagerを直接操作します。

from memory cache : メモリから直接リソースを取得するのではなく、リソースを再ダウンロードせずに次のアクセスを待ちます。

両者の違い プロセスが終了すると、メモリ上のデータはクリアされますが、ディスク上のデータはクリアされません。したがって、次にプロセスが再インストールされたとき、プロセスはdiskCacheからデータを取得できますが、memoryCacheは取得することができません。

キャッシュできないリクエスト

もちろん、すべてのリクエストをキャッシュできるわけではありません。

ブラウザでキャッシュできないリクエスト。

  • HTTPメッセージヘッダにCache-Control:no-cache, pragma:no-cache (HTTP 1.0), Cache-Control:max-age=0 など、キャッシュしないことをブラウザに伝える内容があるリクエスト。
  • クッキーや認証情報などに基づく入力を必要とする動的なリクエストはキャッシュされません
  • HTTPSで安全に暗号化されたリクエスト
  • POSTリクエストはキャッシュできません
  • HTTPレスポンスヘッダにLast-Modified/Etag、Cache-Control/Expiresが含まれないリクエストはキャッシュされません。

以上、個人的な体験談ですが、参考にしていただき、スクリプトハウスをもっと応援していただければと思います。