3

問題:動的サーバーから送信された画像を FireFox にキャッシュさせることができないようです

セットアップ:バックエンドで動的サーバー (mod_perl2) へのリバース プロキシを使用する静的 Apache サーバー。

サーバーのリクエスト URL は次のとおりです。これは動的サーバーに送信され、そこで Cookie を使用して画像へのアクセスが検証されます。

リクエスト ヘッダー

Host:  <OBSCURED>
User-Agent:  Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.15) Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15
Accept:  image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset:  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive:  300
Connection:  keep-alive
Referer: <OBSCURED>
Cookie:  pz_cred=4KCNr0RM15%2FJCOt%2BEa6%2BL62z%2Fxvbp2xNQHY5pJw5d6Q
Pragma:  no-cache
Cache-Control: no-cache

動的サーバーは画像をサーバーにストリーミングし、次の応答を返します。

応答ヘッダー

Date:  Tue, 24 Nov 2009 04:28:07 GMT
Server:  Apache/2.2.11 (Ubuntu) mod_apreq2-20051231/2.6.0 mod_perl/2.0.4 Perl/v5.10.0
Cache-Control: public, max-age=31536000
Content-Length:  25496
Content-Type:  image/jpeg
Via: 1.1 127.0.1.1:8081
Keep-Alive:  timeout=15, max=75
Connection:  Keep-Alive

今のところ、とても良いです(私はそう思います)。ただし、ページをリロードすると、画像がキャッシュされたように見えず、リクエストが再度送信されます。

リクエスト ヘッダー

Host: <OBSCURED>
User-Agent:  Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.15) Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15
Accept:  image/png,image/*;q=0.8,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset:  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive:  300
Connection:  keep-alive
Referer: <OBSCURED>
Cookie:  pz_cred=4KCNr0RM15%2FJCOt%2BEa6%2BL62z%2Fxvbp2xNQHY5pJw5d6Q
Cache-Control: max-age=0

ブラウザが画像をキャッシュする必要があるため、リクエストは発生しないようです。このままでは、最初と同じように 200 応答が受信され、画像が再取得されたように見えます (ただし、ブラウザーはキャッシュされた画像を使用しているように見えます)。

この問題は、上記のリロード リクエスト ヘッダーの Cache-Control: max-age=0 によって示唆されているようです。

なぜこれが起こっているのか誰にも分かりますか?おそらく、問題を引き起こしているのは応答のViaヘッダーでしょうか?

4

3 に答える 3

5

元のリクエストには

Cache-Control: no-cache

これは、すべての中間 HTTP キャッシュ (Firefox を含む) に、キャッシュされた応答を使用したくないことを伝えます。元の Web サーバー自体から応答を取得する必要があります。

応答は次のように述べています。

Cache-Control: public, max-age=31536000

これは、オリジンサーバーに関する限り、応答キャッシュされる可能性があることを全員に伝えます. サーバーは、PNG 画像をキャッシュできるように構成されているようです: HTTP 1.1 (セクション 14.21) は次のように述べています。

注: 応答に max-age ディレクティブ (セクション 14.9.3 を参照) を含む Cache-Control フィールドが含まれている場合、そのディレクティブは Expires フィールドをオーバーライドします。

2 番目のリクエストは次のように述べています。

Cache-Control: max-age=0

これは、すべての中間 HTTP キャッシュに、0 秒より古いキャッシュされた応答を取得しないことを伝えます。

注意すべきことの 1 つは、Firefox で [リロード] ボタンをクリックすると、元の Web サーバーからリロードするように求めていることです。画像のキャッシュをテストするには、ページから離れて戻るか、新しいタブで開きます。最初に no-cache が表示され、2 回目に max-age=0 が表示された理由はわかりません。

ところで、私は Firefox 用の FireBug プラグインが気に入っています。リクエストヘッダーとレスポンスヘッダー、およびその他のあらゆる種類の優れたものを確認できます。

于 2009-11-24T05:29:55.763 に答える
3

私の以前の答えは部分的にしか正しかった。

問題は、FireFox3がリロードイベントを処理する方法です。どうやら、それはほとんどの場合、オリジンサーバーからコンテンツを再度要求します。したがって、Cache-Control: max-age=0リクエストヘッダー。

Firefox、キャッシュされた画像を使用してリロード時にページをレンダリングしますが、それでも「バックグラウンドで」それらを更新するためのすべての要求を行います。次に、入ってくるときにそれらを交換します。

したがって、ページは高速にレンダリングされ、YSlowはキャッシュされたコンテンツを報告します。しかし、サーバーはまだ釘付けになっています。

解決策は、動的サーバースクリプトの着信ヘッダーに問い合わせて、「If-Modified-Since」ヘッダーが提供されているかどうかを判断することです。この場合、コンテンツが変更されていないと判断された場合、HTTP_NOT_MODIFIED(304)応答が返されます。

これは最適ではありません-Firefoxはリクエストをまったく行わない方がいいです-しかし、ページの読み込み時間を半分に短縮し、帯域幅を大幅に削減します。Firefoxがリロードで動作する方法を考えると、これが最善の解決策のようです。

その他のコメント:ページから離れて戻ることについてのJim Ferranのポイントにはメリットがあります。キャッシュは常に使用され、リクエストは送信されません(+1からJimへ)。また、動的に追加されるコンテンツ(たとえば、初期ロード後のAJAX呼び出し)もキャッシュを使用しているように見えます。

これが私以外の誰かに役立つことを願っています:)

于 2009-11-30T23:18:24.367 に答える
1

それを解決したように見えます:

  • ヘッダー経由でプロキシを削除しました
  • 最終変更ヘッダーを追加しました
  • 遠い将来の有効期限を追加しました

Firebugは引き続きオリジンサーバーから200の応答を表示しますが、YSlowは画像をキャッシュされたものとして認識します。YSlowによると、フレッシュ時の合計画像ダウンロードサイズは500Kを超えています。キャッシュがプライミングされると、0Kのダウンロードサイズが表示されます。

これは、トリックを実行するOriginサーバーからの応答ヘッダーです。

Date: Tue, 24 Nov 2009 08:54:24 GMT
Server: Apache/2.2.11 (Ubuntu) mod_apreq2-20051231/2.6.0 mod_perl/2.0.4 Perl/v5.10.0
Last-Modified: Sun, 22 Nov 2009 07:28:25 GMT
Expires: Tue, 30 Nov 2010 19:00:25 GMT
Content-Length: 10883
Content-Type: image/jpeg
Keep-Alive: timeout=15, max=89
Connection: Keep-Alive

画像をリクエストする方法のため、これらの日付が静的であるかどうかは実際には問題ではありません。私のアプリは、画像をリクエストする前の最後のmod時刻を認識しており、これをクライアント側のリクエストURLに追加して、画像バージョンごとに一意のURLを作成します(例: http: //myserver.com/img/125.jpg?20091122(情報はAJAXJSONフィードから取得されます)。たとえば、最終更新日を2000年1月1日とし、有効期限を2050年のいつかにすることができます。

YSlowが正しい場合(パフォーマンステストで正しいことが示されている場合)、FireBugは、200応答ではなく、これらのローカルキャッシュヒットを実際に報告する必要があります。

于 2009-11-24T09:02:08.877 に答える