web-dev-qa-db-ja.com

サーバー内のファイルが変更された場合にのみ、Apacheでイメージを期限切れにして強制的にリロードする方法

Apache2サーバーでPHPアプリケーションを実行しています。HTML5ボイラープレートから始めました。.htaccessには、すべての画像の「1か月」の有効期限ポリシーが含まれています。例:

ExpiresByType image/jpeg                            "access plus 1 month"

私のアプリケーションでは、ユーザーが既存の画像を(同じ名前とパスで)新しい画像に置き換えることもできます。ただし、置き換えられると、ユーザーはページが強制的に更新されるまで古い画像を表示し続けます(たとえば、 Ctrl-F5)。

技術的には、画像は1か月後に期限切れになるように設定されているため、ブラウザがサーバーに画像を要求しないことにログから気づきました。強制更新の場合にのみ、ブラウザはそれを要求します。その時点で、Apache2は304を発行するか(ファイルが変更されていない場合)、新しいイメージを200で送信します(変更された場合)。

私が欲しいのは:への単純で簡単なメカニズムです

  • 画像が今から1か月後に期限切れになる既存の設定を維持します。ブラウザがすでに持っている場合は、それをフェッチする必要はありません。
  • ただし、ユーザーが画像を更新した場合は、ブラウザに新しい画像を自動的に取得させます。更新を強制するようにユーザーに指示する必要はありません。
  • 新しい画像のフェッチは、最後のポイント以降、他のユーザーまたは他のブラウザにも拡張する必要があります。

別の方法として特定のパスに対してのみ有効期限ポリシーを「即時」に条件付きで設定できてもかまいません(他のフォルダー内の画像は一般的な有効期限ポリシーに従う必要があります)。たくさんの304と一緒に暮らすことができます。私は推測する。

ファイル名を単に新しいものに変更したくありません。ファイル名は動的に生成され、いくつかあります。「新しい名前」を追跡すると、複雑さが増します。 (他に簡単な解決策がない場合でも、これを調査する必要があります。)

1
ADTC

あなたは多くのことを求めています:いくつかのデータが1か月間有効であることを明示的に構成しますが、気が変わったらすぐには有効になりません。一般的に、あなたはあなたの決心をしなければならないでしょう。

  • 304があなたを傷つけない場合:間隔を短くすることが解決策かもしれません
  • この問題の一般的な緩和策には、画像へのタイムスタンプパラメータが含まれます。タイムスタンプがすべてのアプリケーションで静的である(およびユーザーの裁量で更新される)場合は、logo.pngをロードせず、logo.png?t=20160327083700をロードします。ファイルの最終変更日(サーバー側の負担が追加されます)
  • コメントに続いて、パスの他の場所にタイムスタンプを追加することもできます(画像名が同じままになるように):/20160327083700/logo.png。ただし、時期尚早の最適化に関する私の最後の段落を読んでください

リソースが長期間有効であるとみんなに言っている限り、彼らがあなたのWordをそのリソースとして受け取り、時間が終わるまでそれを再利用することに驚かないでください。

上記のタイムスタンプパラメータには、ある程度読みやすいタイムスタンプを使用しました(例:今日)。 1970年以降のフォーマットされていないミリ秒、または簡単に取得できるフォーマットされていない値を使用することをお勧めします。ファイルを更新するたびに変更する必要があります。

編集:コメントで述べているように、ブラウザはURLの?をキャッシュバイパスとして解釈する傾向があり、リソースを早期に再度要求する方が適切です。それで、あなたの最善の策は期間を短くすることかもしれません。特に304年代を生き残ると言うときは、"access plus 1 hour"(または10分)まで下がってください。とにかくこれは正しいことです:状態thatコンテンツは1か月間キャッシュできますその場合のみ 1か月間キャッシュできます。

ちなみに、「時期尚早の最適化はすべての悪の根源である」という古いことわざを思い出させてください。"access plus 1 month"はパフォーマンスチューニングセッションからではなく、あなたの推測から来たに違いありません。そして、この質問でわかるように、この時期尚早な最適化は、実際には、それがもたらした競合を解決するためにたくさん余分な作業を引き起こします。

1
Olaf