web-dev-qa-db-ja.com

Chrome ETagヘッダーを無視し、メモリ内キャッシュ/ディスクキャッシュのみを使用します

私が正しく理解していれば、ETagを使用するためのフローは次のように機能します。

  • ブラウザはリクエストをサーバーに送信します。サーバーはETagを使用して画像を送り返します
  • ブラウザはETagと一緒にリソースを保存します
  • 次のリクエストで、ブラウザは保存されたETagを含むヘッダーIf-None-Matchを使用してリクエストを送信します。

応答を返すとき、chrome開発ツールは、これらが私のヘッダーであると教えてくれます

Cache-Control:max-age=7200
Connection:keep-alive
Content-Type:image/png
Date:Thu, 27 Apr 2017 13:42:57 GMT
ETag:"b36f59c868d4678033d318a182658e18371df8f5"
Expires:Thu, 27 Apr 2017 15:42:57 GMT
Server:nginx
Transfer-Encoding:chunked
X-Debug-Token:873c8f
X-Debug-Token-Link:http://localhost:8081/_profiler/873c8f

しかし、ページをリロードしても、新しい画像は収集されません。ここに表示されているように、Chromeのメモリ内キャッシュまたはディスクキャッシュを介して保存されます

Chrome dev tab

しかし、なぜこれが起こっているのですか? ETagを送信したのに、ブラウザがサーバーに別のリクエストを行わず、代わりに独自のキャッシュを使用するのはなぜですか?

私が尋ねている理由は、画像をキャッシュしたいのですが、画像が変更されたらすぐに更新する必要があるからです。なぜChromeそうするのですか?

更新
Firefoxで意図したとおりに機能することに気付いたので、これはchrome "feature"であり、構成ではないようです。

アップデート2
このような画像の新しいヘッダーを設定した後

Cache-Control:max-age=0, private
Connection:keep-alive
Content-Type:image/png
Date:Thu, 27 Apr 2017 14:44:57 GMT
ETag:"e5b18bdebe44ed4bba3acb6584d9e6a81692ee27"
Expires:Fri, 27 Oct 2017 14:44:57 GMT
Server:nginx
Transfer-Encoding:chunked
X-Debug-Token:3447a6
X-Debug-Token-Link:http://localhost:8081/_profiler/3447a6

Chromeは引き続きディスクキャッシュを使用してデータをロードします。これは私のnginxです

location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
  access_log off;
  add_header Cache-Control "max-age: 0, must-revalidate";
}

アップデート3
私はさらに調査を行いました。 Expiresタグが設定されるとすぐに、Chromeはメモリ内またはディスクキャッシュを使用します。max-ageと同じです。must-revalidateが設定されていても、Expiresが設定されるとすぐにわかりません。またはmax-age=>0が設定されている場合、Chromeはリソースをリロードしません。

11
Musterknabe

サーバーはchromeリソースが次の2時間(7200秒)の間有効であることを通知しています。おそらく、2番目の要求はそれよりも早かったでしょう。

max-age: 0またはおそらくmax-age: 0, must-revalidateを使用したほうがよいでしょう。次に、完全にキャッシュされた操作を取得することは決してありませんが(サーバーにアクセスすることさえ気にしないで)、サーバーに304 Not Modified応答を送信させて、キャッシュされたエンティティを使用できることをブラウザーに通知する(およびメタデータを更新する)ことができます。該当する場合はヘッダーに基づく)したがって、要求/応答がまだ発生している間は、エンティティが何キロバイト以上あるかではなく、約300バイトのみが送信されます。

5
Jon Hanna

これは古い投稿ですが、これが私たちがそれを解決した方法です。

@Musterknabe更新に関するコメント3:

must-revalidate chromeを設定した後でも、同じことが起こりました。新しいリソースをリロードしていませんでした。リソースはクライアント/ブラウザのキャッシュメモリにすでに存在しているため、提供されていることがわかりました。メモリキャッシュから、新しいリクエスト(静的リソースを取得するため)が発生しなかったため、応答ヘッダーはmust-revalidateで更新されませんでした

この問題を修正するために、2つの手順を使用しました:
1。変更されたリソースファイル名-新しいリクエストが確実に実行されるようにするため
2。静的ファイルにキャッシュ制御ヘッダーを追加しました(startup.cs内)-将来の静的リソースファイルの変更に対応するため。そのため、今後はリソースファイル名を変更する必要はありません。

    public void Configure(IApplicationBuilder app)
    {
        app.UseStaticFiles(new StaticFileOptions
        {
            OnPrepareResponse = ctx =>
            {
                const int durationInSeconds = 0;
                ctx.Context.Response.Headers[HeaderNames.CacheControl] =
                    "must-revalidate,max-age=" + durationInSeconds;
            }
        });
    }

それが役に立てば幸い。

0
S52