web-dev-qa-db-ja.com

ResponseCache属性はクライアント側のデータをキャッシュしません

ASP.NET Coreアプリケーションには、一部のデータを返すアクションメソッドがあります。このデータをキャッシュしたかったクライアント側ドキュメントはこちら に基づいて、アクションメソッドでResponseCache属性を使用できます。この属性は、応答にCache-Controlヘッダーを追加します

応答のキャッシュとは、ASP.NET Core MVCアクションによって行われるHTTP応答にキャッシュ関連のヘッダーを指定することです。これらのヘッダーは、クライアントおよび中間(プロキシ)マシンが特定の要求に対する応答をキャッシュする方法を指定します(ある場合)。同じアクションに対する将来のリクエストはクライアントまたはプロキシのキャッシュから提供される可能性があるため、これにより、クライアントまたはプロキシがWebサーバーに行うリクエストの数を減らすことができます。

また

応答キャッシュは、Webサーバー上の応答をキャッシュしません。これは、以前のバージョンのASP.NETおよびASP.NET MVCのサーバーのメモリに応答をキャッシュする出力キャッシュとは異なります。

これが私のアクションメソッドの外観です

public class LookupController : Controller
{
    [HttpGet]
    [ResponseCache(Duration = 120)]
    public IEnumerable<StateProvinceLookupModel> GetStateProvinces()
    {
        return _domain.GetStateProvinces();
    }
}

次に、ブラウザを使用してメソッドを http:// localhost:40004/lookup/getstateprovinces として呼び出します。これは、要求ヘッダーと応答ヘッダーです。

enter image description here

期待どおりに、応答ヘッダーにCache-Control: public,max-age-120があることに注意してください。ただし、F5(120秒前)を使用してページを更新すると、常にGetStateProvinceアクションメソッド内のデバッガーブレークポイントがヒットします。つまり、クライアント側でデータをキャッシュしません。

クライアント側のキャッシュを有効にするために他に必要なことはありますか?

UpdateIE、ChromeおよびPOSTMANも運が悪かった。私がアドレスバーにURLを入力するたびにまたは、クライアント(ブラウザまたはポストマン)の更新をヒットすると、アクションメソッドが呼び出されます。

18
LP13

実際ResponseCache属性は意図したとおりに機能します。
違いは、ウェブサイトのページをナビゲートする場合(ケース1)、または戻るボタンと進むボタン( ページの更新時ではありません)。

ケース1の例として、次のようにします。

記事 ASP.Net Core 1.1の応答キャッシュ でわかるように、次のように記述されています。

ブラウザセッション中に、Webサイト内の複数のページを閲覧したり、[戻る]ボタンや[進む]ボタンを使用してページにアクセスすると、コンテンツはローカルのブラウザキャッシュから提供されます(期限切れでない場合)。
しかし、ページがF5経由で更新されると、リクエストはサーバーに送られ、ページコンテンツが更新されます。 F5を使用して連絡先ページを更新することで確認できます。
F5を押すと、応答キャッシュの有効期限の値は、コンテンツを提供するために果たす役割がありません。連絡先要求に対して200応答が表示されるはずです。

参照:
[1]。 ASP.NET Core Response Caching Sample
[2]。 ResponseCache属性サンプル
[3]: すべてのブラウザーでWebページのキャッシュを制御する方法?

12
Michael

要するに、次のようなResponseCache属性を使用すれば、有効期限ベースのクライアント側キャッシングをまったく新しいデフォルトのドットネットコアプロジェクト(asyncメソッドを含む)で機能させるのに十分です。

_[HttpGet]
[ResponseCache(Duration = 120)]
public IEnumerable<StateProvinceLookupModel> GetStateProvinces()
{
    return _domain.GetStateProvinces();
}
_

上のスクリーンショットでは、_Cache-Control: public,max-age=120_が表示されているため、これは正しく機能しています。ほとんどの場合、ブラウザーは有効期限が切れる前(つまり、次の120秒または2分間)に後続の要求を送信しませんが、これはブラウザー(または他のクライアント)の決定です。

リクエストisが送信された場合でも、ミドルウェアまたはサーバーの構成によって応答ヘッダーが上書きされているか、クライアントがキャッシュディレクティブを無視しています。上のスクリーンショットでは、キャッシュコントロールヘッダーが存在するため、クライアントはキャッシュを無視します。

クライアントキャッシュが無視され、リクエストが送信される一般的なケース:

  • Chrome 防止 証明書なしでHTTPSを使用する場合のあらゆる種類のキャッシュ(または無効な証明書、これは多くの場合ローカル開発で一般的であるため、キャッシュのテスト時には必ずHTTPを使用するか、自己署名を信頼してください証明書)
  • ほとんどのブラウザ開発ツールは、開いたときにデフォルトでキャッシュを無効にします。これは無効にすることができます
    • ブラウザは通常、追加のヘッダーを送信します、Chromeは_Cache-Control: no-cache_を送信します
  • 直接更新する(つまり、Ctrl + F5)と、ほとんどのブラウザーはキャッシュを使用せず、年齢に関係なくリクエストを行うように指示されます
    • ブラウザは通常、追加のヘッダーを送信しますChromeは_Cache-Control: max-age=0_を送信します(これはスクリーンショットに表示されています)
  • Postmanは、ローカルキャッシュをバイパスする_Cache-Control: no-cache_ヘッダーを送信し、その結果、要求が送信されます。設定ダイアログから無効にできます。その場合、上記のクライアントキャッシュ構成ではリクエストが送信されなくなります。

この時点では、有効期限ベースのクライアントキャッシングを超えており、サーバーwillは何らかの方法でリクエストを受信し、別のキャッシングレイヤーが発生します。サーバーに_304 Not Modified_コード(クライアントが自由に解釈できるようにする)か、サーバー側のキャッシュを使用して完全なコンテンツで応答します。または、後続のキャッシュを使用せずに、サーバー上で要求処理全体を再度実行するだけでもかまいません。


注:ResponseCache属性は、スタートアップコンフィギュレーションのservices.AddResponseCaching()app.UseResponseCaching()ミドルウェアと混同しないでください。ミドルウェアを使用する場合、デフォルトではメモリ内キャッシュを使用します)。クライアントキャッシュが機能するためにミドルウェアは必要ありません。属性自体で十分です。

4
John Weisz