1. ホーム
  2. http

[解決済み】全てのブラウザで、Webページのキャッシュを制御するには?

2022-03-18 12:49:20

質問

調査の結果、すべてのブラウザがHTTPキャッシュディレクティブを統一的に尊重するわけではないことがわかりました。

セキュリティ上の理由から、私たちのアプリケーションの特定のページをキャッシュさせたくないのです。 を使用します。 をWebブラウザで実行します。少なくとも以下のブラウザで動作する必要があります。

  • インターネットエクスプローラー6以上
  • Firefox 1.5 以上
  • サファリ 3 以上
  • Opera 9 以上
  • クローム

私たちの要求は、セキュリティテストに由来しています。私たちのウェブサイトからログアウトした後、戻るボタンを押すとキャッシュされたページを見ることができるのです。

解決方法は?

はじめに

すべてのクライアント (およびプロキシ) で機能する、正しい最小限のヘッダセットです。

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

Cache-Control は、クライアントとプロキシのための HTTP 1.1 仕様に従ったものです (そして、一部のクライアントでは Expires ). また Pragma は、前時代的なクライアントのためのHTTP 1.0仕様に従ったものです。その Expires は、クライアントとプロキシのための HTTP 1.0 と 1.1 の仕様に従います。HTTP 1.1 では Cache-Control よりも優先されます。 Expires ということで、結局のところ、HTTP 1.0プロキシ専用ということになります。

IE6 とその壊れたキャッシュを気にしないのであれば、 HTTPS でページを提供する際に no-store を省略することができます。 Cache-Control: no-cache .

Cache-Control: no-store, must-revalidate
Pragma: no-cache
Expires: 0

IE6 や HTTP 1.0 クライアント (HTTP 1.1 は 1997 年に導入されました) を気にしないのであれば、以下のように Pragma .

Cache-Control: no-store, must-revalidate
Expires: 0

HTTP 1.0プロキシも気にしないのであれば、以下のように Expires .

Cache-Control: no-store, must-revalidate

一方、サーバーが自動的に有効な Date ヘッダがあれば、理論的には Cache-Control に依存しています。 Expires のみです。

Date: Wed, 24 Aug 2016 18:32:02 GMT
Expires: 0

しかし、例えばエンドユーザーがOSの日付を操作し、クライアントソフトウェアがそれに依存している場合、失敗する可能性があります。

その他 Cache-Control などのパラメータがあります。 max-age は、上記の Cache-Control パラメータが指定されています。また Last-Modified ヘッダーは、他のほとんどの回答で含まれているように、ここでは のみ の場合、面白いです。 実際に欲しいのは を指定すると、リクエストがキャッシュされるため、指定する必要は全くありません。

設定方法は?

PHPを使用する。

header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1.
header("Pragma: no-cache"); // HTTP 1.0.
header("Expires: 0"); // Proxies.

Java Servlet、またはNode.jsを使用します。

response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setHeader("Expires", "0"); // Proxies.

ASP.NET-MVCを使用する

Response.Cache.SetCacheability(HttpCacheability.NoCache);  // HTTP 1.1.
Response.Cache.AppendCacheExtension("no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.

ASP.NET Web APIを使用する。

// `response` is an instance of System.Net.Http.HttpResponseMessage
response.Headers.CacheControl = new CacheControlHeaderValue
{
    NoCache = true,
    NoStore = true,
    MustRevalidate = true
};
response.Headers.Pragma.ParseAdd("no-cache");
// We can't use `response.Content.Headers.Expires` directly
// since it allows only `DateTimeOffset?` values.
response.Content?.Headers.TryAddWithoutValidation("Expires", 0.ToString()); 

ASP.NETを使用。

Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.

ASP.NET Core v3を使って

// using Microsoft.Net.Http.Headers
Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate";
Response.Headers[HeaderNames.Expires] = "0";
Response.Headers[HeaderNames.Pragma] = "no-cache";

ASPを使用する。

Response.addHeader "Cache-Control", "no-cache, no-store, must-revalidate" ' HTTP 1.1.
Response.addHeader "Pragma", "no-cache" ' HTTP 1.0.
Response.addHeader "Expires", "0" ' Proxies.

Ruby on Railsを使用。

headers["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
headers["Pragma"] = "no-cache" # HTTP 1.0.
headers["Expires"] = "0" # Proxies.

Python/Flaskを使用。

response = make_response(render_template(...))
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
response.headers["Pragma"] = "no-cache" # HTTP 1.0.
response.headers["Expires"] = "0" # Proxies.

Python/Djangoを使用。

response["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
response["Pragma"] = "no-cache" # HTTP 1.0.
response["Expires"] = "0" # Proxies.

Python/Pyramidを使用。

request.response.headerlist.extend(
    (
        ('Cache-Control', 'no-cache, no-store, must-revalidate'),
        ('Pragma', 'no-cache'),
        ('Expires', '0')
    )
)

Goを使用する。

responseWriter.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") // HTTP 1.1.
responseWriter.Header().Set("Pragma", "no-cache") // HTTP 1.0.
responseWriter.Header().Set("Expires", "0") // Proxies.

Clojure (require Ring utils)を使用します。

(require '[ring.util.response :as r])
(-> response
  (r/header "Cache-Control" "no-cache, no-store, must-revalidate")
  (r/header "Pragma" "no-cache")
  (r/header "Expires" 0))

Apacheを使用する .htaccess ファイルを作成します。

<IfModule mod_headers.c>
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
</IfModule>

HTMLを使用する。

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

HTMLメタタグとHTTPレスポンスヘッダの比較

重要なことは、HTML ページが HTTP 接続で提供され、ヘッダーが 両方とも HTTPレスポンスヘッダとHTMLの <meta http-equiv> を指定した場合、HTTPレスポンスヘッダで指定されたものがHTMLメタタグより優先されます。HTMLメタタグは、ページがローカルディスクのファイルシステムから file:// のURLでご覧いただけます。以下もご参照ください。 W3 HTML仕様 5.2.2章 . プログラム的に指定しない場合、ウェブサーバーはデフォルト値を含むことができるため、この点には注意してください。

一般的には ではなく は、スターターによる混乱を避けるために HTML meta タグを指定し、ハード HTTP レスポンスヘッダに依存します。さらに、特にそれらの <meta http-equiv> タグは 無効 をHTML5で表示します。のみです。 http-equiv に記載されている値は HTML5仕様 が許可されます。

実際のHTTPレスポンスヘッダを確認する

一方と他方を確認するには、ウェブブラウザの開発者向けツールセットのHTTPトラフィックモニターで確認/デバッグすることができます。Chrome/Firefox23+/IE9+でF12キーを押し、"Network" または"Net" タブパネルを開き、関心のあるHTTPリクエストをクリックすると、HTTPリクエストとレスポンスのすべての詳細を明らかにすることができます。また 以下のスクリーンショット はChromeのものです。

ファイルのダウンロードにもこのヘッダを設定したい

まず第一に、この質問と回答は、quot;ウェブページ(HTMLページ)を対象としており、quot;ファイルダウンロード(PDF、zip、Excelなど)を対象としているわけではありません。キャッシュし、URIパスやクエリー文字列のどこかにあるファイルバージョン識別子を利用して、ファイルが変更された場合に強制的に再ダウンロードするようにした方がよいでしょう。ファイルダウンロードにキャッシュなしヘッダを適用する場合、HTTPではなくHTTPSでファイルダウンロードを提供する場合、IE7/8のバグに注意してください。詳しくは IEはfoo.jsfをダウンロードすることができません。IE はこのインターネットサイトを開くことができませんでした。要求されたサイトは利用できないか、または見つかりません。 .