49

ここで多くの記事といくつかの質問を読んだ後、私はついにApachemod_expiresをアクティブ化して、ブラウザーに1年間画像をキャッシュする必要があることを通知することに成功しました。

<filesMatch "\.(ico|gif|jpg|png)$">
  ExpiresActive On
  ExpiresDefault "access plus 1 year"
  Header append Cache-Control "public"
</filesMatch>

そしてありがたいことに、サーバーの応答は正しいようです。

HTTP/1.1 200 OK 
Date: Fri, 06 Apr 2012 19:25:30 GMT 
Server: Apache 
Last-Modified: Tue, 26 Jul 2011 18:50:14 GMT 
Accept-Ranges: bytes 
Content-Length: 24884 
Cache-Control: max-age=31536000, public 
Expires: Sat, 06 Apr 2013 19:25:30 GMT
Connection: close
Content-Type: image/jpeg 

そうですね、これでブラウザのダウンロードが停止し、サーバーに1年間画像について問い合わせることさえできると思いました。しかし、それは部分的に真実です。ブラウザを閉じて再度開くと、ブラウザはサーバーから画像をダウンロードしなくなりますが、ブラウザは各画像のHTTPリクエストでサーバーに問い合わせます

各画像に対するHTTPリクエストの作成をブラウザに強制的に停止させるにはどうすればよいですか?これらのHTTPリクエストの後に画像がダウンロードされない場合でも、サーバーに対して行われるリクエストであるため、レイテンシが不必要に増加し、ページのレンダリングが遅くなります。

私はすでにブラウザに画像を1年間キャッシュに保持しなければならないと言いました!なぜブラウザは(画像をダウンロードしなくても)各画像についてサーバーに問い合わせるのですか?!


FireBugのネットワークグラフを見ると([FireBug]> [ネット]>[画像]メニュー)、さまざまなキャッシュ動作を確認できます(明らかに、ブラウザーキャッシュを完全に空にして開始し、[すべての履歴をクリア]を使用してブラウザーでキャッシュを強制的に削除しました)。

  • ページが初めて読み込まれると、すべての画像がダウンロードされます(ブラウザの[ページの再読み込み]ボタンをクリックしてページを強制的に再読み込みした場合も同じことが起こります)。意味あり!

  • サイトをナビゲートして同じページに戻ると、画像はまったくダウンロードされず、ブラウザはサーバーに画像を問い合わせることさえしませんこれは理にかなっています(そして、ブラウザが閉じているときもこの動作を見たいです)!

  • ブラウザを閉じて同じページでもう一度開くと、ばかげたブラウザはとにかく画像ごとに1回サーバーにHTTPリクエストを送信します。画像をダウンロードしませんが、それでもHTTPリクエストを送信します。これは、ブラウザが問い合わせるようなものです。画像に関するサーバー(サーバーは200 OKで応答します)。これは私を苛立たせるものです!

興味があれば、以下のグラフも添付します。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

編集:FireFox 3.6が古すぎるという問題ではないことを確認するために、FireFox11.0でもテストしました。同じことが起こります!!! GoogleサイトとStackoverflowサイトもテストしましたが、どちらも送信しますCache-Control: max-age=...、ブラウザを閉じて同じページで再度開くと、ブラウザはサーバーにHTTPリクエストを送信します。サーバーの応答後、ブラウザはダウンロードしません。画像(上で説明したように)ですが、それでもページを表示する時間が長くなるようなリクエストが発生します。

EDIT2:ここLast-Modifiedで提案されているようにヘッダーを削除しても、問題は解決せず、違いはありません。

4

10 に答える 10

27

表示されている動作は、意図されたものであり(詳細については、RFC7234を参照)、指定された動作です。

最新のブラウザはすべて、キャッシュステータスに関係なく、表示されるすべてのページ要素に対してHTTPリクエストをサーバーに送信します。これは、HTTPサーバーがすべての要素のすべての表示の記録を維持できるようにするために、Webサービス(特に広告ネットワーク)の要求に応じて行われた設計上の決定でした。

ブラウザがこれらの要求を行わなかった場合、画像がユーザーに表示されたことをサーバーに通知することはありません。広告ネットワークの場合、これは壊滅的です。早い段階で、広告ネットワークはランダムに生成された名前を使用して同じ広告画像を配信することにより、これを回避する方法を「ハッキング」しました(例:「coke_ad_1_98719283719283.gif」)。ただし、ISPの場合、ISPが運用しているキャッシュ/プロキシサーバーをバイパスして、すべてのユーザーがこれらの同一の広告画像を再ダウンロードしていたため、この方法によりデータ転送が大幅に増加しました。

そのため、問題が発生しました。有効期限が切れていないキャッシュ要素であっても、ブラウザは常にHTTPリクエストを送信していました。サーバーはHTTP304ステータスコード(「変更されていない」)で応答します。これにより、サーバーは画像がクライアントに表示されたという事実を記録できます。その結果、広告ネットワークは通常、ネットワークキャッシュサーバーをバイパスするためにランダム化された画像名の使用を停止しました。

これにより、広告ネットワークに必要なもの(表示されたすべての画像の記録)が提供され、ISPに必要なもの(キャッシュ可能な画像と静的コンテンツ)が提供されました。

そのため、ブラウザがキャッシュされたページ要素に対してHTTPリクエストを送信しないようにするためにできることはあまりありません。

しかし、html5に付属している他の利用可能なクライアント側ソリューションを見ると、リソースの読み込みを防ぐ余地があります

  1. キャッシュマニフェスト(その落とし穴にもかかわらず)
  2. IndexedDB(優れた非同期機能、BLOBストレージを可能にする)
  3. ローカルストレージ(非同期ではない)
于 2012-04-16T15:21:40.243 に答える
17

リクエストの分析に間違ったツールを使用していました。

ネットワーク上で実際に何が起こっているかを確認できるように、非常に便利なFirefoxアドオンのLiveHTTPヘッダーをお勧めします。

念のために言っておきますが、サーバーをssh / putteして、次のようなことを行うことができます。

tail -f /var/log/apache2/access.log
于 2012-05-16T14:52:43.237 に答える
12

「リロード」と「リフレッシュ」には違いがあります。通常、戻るボタンと進むボタンを使用してページに移動するだけでは、新しいHTTPリクエストは開始されませんが、特にF5キーを押してページを「更新」すると、ブラウザはキャッシュを再確認します。これはブラウザに依存しますが、FFとChrome(つまり、ネットワークトラフィックを簡単に監視できるブラウザ)の標準のようです。F6を押してEnterキーを押すと、URLアドレスバーにフォーカスしてから「移動」する必要があります。ページをリロードしますが、ページのアセットを再確認しないでください。

更新:前後のナビゲート動作の明確化。これは、ブラウザでは「バックフォワードキャッシュ」またはBFCacheと呼ばれます。戻る/進むボタンでナビゲートするときの目的は、自分のタイムラインで見たときのページとまったく同じように表示することです。サーバーのキャッシュヘッダーに特定のアイテムの有効期限が切れていると表示されている場合でも、前後の使用時にサーバー要求は行われません。

開発者のネットワークパネルに(200 OK BFCache)が表示されている場合は、サーバーがヒットすることはありません。

http://www.softwareishard.com/blog/firebug/firebug-tip-what-the-heck-is-bfcache/

于 2013-02-02T17:43:47.067 に答える
7

F5またはF5+Ctrlを使用して強制的に更新すると、リクエストが送信されます。ただし、ブラウザを閉じてURLをもう一度入力すると、要求は送信されません。リクエストが送信されるかどうかをテストする方法は、リクエストが送信されない場合でもサーバーのbeginリクエストにブレークポイントを使用することでした。Firebugでは7ミリ秒の待機を行ったと表示されるので注意してください。

于 2012-04-12T15:32:19.470 に答える
6

ここで説明していることは、私の経験を反映していません。コンテンツがno-storeディレクティブで提供される場合、または明示的な更新を行う場合は、はい、元のサーバーに戻ることを期待します。そうでない場合は、ブラウザーの再起動時にキャッシュする必要があります(許可されており、書き込みが可能であると想定しています)。キャッシュファイル)。

滝をもう少し詳しく見ると(少し小さくてぼやけているので注意が必要です)、ブラウザは本来の動作をしているように見えます-画像のエントリがあります-しかし、これらはローカルキャッシュからロードされているだけであり、オリジンサーバーから-応答の「日付」ヘッダーを確認します(なぜ秒ではなくミリ秒かかると思いますか?)。そのため、色が異なります。

于 2012-04-07T22:01:41.010 に答える
4

私自身が合理的な答えを探すのにかなりの時間を費やした後、私は以下のリンクが最も有用であるとわかりました、そしてそれはここで尋ねられた質問に答えます。

https://webmasters.stackexchange.com/questions/25342/headers-to-prevent-304-if-modified-since-head-requests

于 2014-02-04T00:16:06.437 に答える
0

それが生死の問題である場合(この方法でページの読み込みを最適化したい場合、またはサーバーの負荷を可能な限り減らしたい場合)、回避策があります。

HTML5ローカルストレージを使用して、画像が初めてリクエストされた後に画像をキャッシュします。

  • [+]ブラウザがHTTPリクエストを送信しないようにすることができます。これは、ユーザーがどれほどハードに試行しても(F5、ctrl + F5、単にページを再訪するなど)、99%で304(変更なし)を返します。

  • [-]このためのjavascriptサポートにいくつかの追加の努力を払う必要があります。

  • [-]画像はbase64に保存されます(バイナリデータは保存できません)。そのため、クライアント側で毎回デコードされます。これは通常、かなり高速で大したことではありませんが、それでもクライアント側での追加のCPU使用率であるため、注意する必要があります。

  • [-]ローカルストレージには制限があります。ドメインごとに最大5MBのデータを使用することを目指すことができます(注:base64は画像の元のサイズに最大30%を追加します)。

  • [?]ほとんどのブラウザでサポートされています。http://caniuse.com/#search=localstorage

テスト

于 2014-12-01T05:05:01.930 に答える
0

Chromeに表示されているのは、実際のHTTPリクエストの記録ではなく、アセットリクエストの記録です。Chromeはこれを実行して、アセットが実際にページからリクエストされていることを示します。ただし、このビューは、要求が行われているかどうかを実際に示すものではありません。アセットがキャッシュされている場合、Chromeが実際に基になるHTTPリクエストを作成することはありません。

タイムラインの紫色のセグメントにカーソルを合わせると、これを確認することもできます。キャッシュされたリソースには(from cache)、ツールチップが含まれます。

実際のHTTPリクエストを確認するには、下位レベルを調べる必要があります。一部のブラウザでは、これはプラグイン(Live HTTPヘッダーなど)を使用して実行できます。

ただし、実際には、リクエストが実際に行われていないことを確認するには、サーバーログを確認するか、CharlesやFiddlerなどのデバッグプロキシを使用する必要があります。これはHTTPレベルで機能し、リクエストが実際に発生していないことを確認します。

于 2014-12-18T16:15:54.257 に答える
0

キャッシュの検証と304の応答

Internet Explorerが、キャッシュされたエントリが有効かどうかを確認する必要がある状況はいくつかあります。

  • キャッシュされたエントリには有効期限がなく、コンテンツはブラウザセッションで初めてアクセスされます

  • キャッシュされたエントリには有効期限がありますが、有効期限が切れています

  • ユーザーが[更新]ボタンをクリックするか、F5キーを押して、ページの更新をリクエストしました

キャッシュされたエントリに最終変更日がある場合、IEはそれをGET要求メッセージのIf-Modified-Sinceヘッダーで送信します。

GET /images/logo.gif HTTP/1.1
Accept: */*
Referer: http://www.google.com/
Accept-Encoding: gzip, deflate
If-Modified-Since: Thu, 23 Sep 2004 17:42:04 GMT
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;)
Host: www.google.com

サーバーはIf-Modified-Sinceヘッダーをチェックし、それに応じて応答します。指定された日時以降にコンテンツが変更されていない場合は、ステータスコード304とヘッダーのみを含む応答メッセージで応答します。

HTTP/1.1 304 Not Modified
Content-Type: text/html
Server: GWS/2.1
Content-Length: 0
Date: Thu, 04 Oct 2004 12:00:00 GMT

応答にはコンテンツが含まれておらず、IEが必要なデータをキャッシュから読み取るため、応答をすばやくダウンロードできます。事実上、これはローカルブラウザキャッシュへのリダイレクトのようなものです。

要求されたオブジェクトがIf-Modified-Sinceヘッダーの日付/時刻以降に実際に変更された場合、サーバーはステータスコード200で応答し、変更されたバージョンのリソースを提供します。

于 2015-02-22T17:13:10.757 に答える
0

この質問は、ウェブマスターのスタック交換サイトでより良い答えがあります。

上記のリンクにも引用されている詳細については、httpwatchをご覧ください。

記事によると:

Internet Explorerが、キャッシュされたエントリが有効かどうかを確認する必要がある状況はいくつかあります。

  • キャッシュされたエントリには有効期限がなく、コンテンツはブラウザセッションで初めてアクセスされます
  • キャッシュされたエントリには有効期限がありますが、有効期限が切れています
  • ユーザーが[更新]ボタンをクリックするか、F5キーを押して、ページの更新をリクエストしました

    ここにコードを入力してください

于 2015-11-12T23:28:52.333 に答える