web-dev-qa-db-ja.com

一部の画像のキャッシュを無効にする

PHP libを使用していくつかの画像を生成します。

ブラウザは、新しく生成されたファイルをロードしない場合があります。

自分で動的に作成された画像に対してのみキャッシュを無効にするにはどうすればよいですか?

注:作成したイメージには、同じ名前を使用する必要があります。

97
dole doug

ハックのように感じるが、かなり移植性があるこの問題に対する一般的で簡単な解決策は、ランダムに生成されたクエリ文字列を動的画像の各リクエストに追加することです。

したがって、たとえば-

<img src="image.png" />

になるだろう

<img src="image.png?dummy=8484744" />

または

<img src="image.png?dummy=371662" />

Webサーバーの観点からは同じファイルにアクセスしますが、ブラウザーの観点からはキャッシュを実行できません。

乱数の生成は、ページを提供するときにサーバーで(ページ自体がキャッシュされていないことを確認してください...)、またはクライアントで(JavaScriptを使用して)行われます。

Webサーバーがこのトリックに対処できるかどうかを確認する必要があります。

206
Hexagon

ブラウザのキャッシュ戦略は、HTTPヘッダーによって制御できます。本当にヒントにすぎないことを忘れないでください。ブラウザはこの(およびその他の)フィールドで非常に一貫性がないため、さまざまなブラウザで目的の効果を得るにはいくつかのヘッダーが必要です。

header ("Pragma-directive: no-cache");
header ("Cache-directive: no-cache");
header ("Cache-control: no-cache");
header ("Pragma: no-cache");
header ("Expires: 0");
41
lhunath

ソリューション1は素晴らしいではありません。それは動作しますが、画像ファイルの最後にハッキングされたランダムまたはタイムスタンプ付きのクエリ文字列を追加すると、ブラウザが再ダウンロードされます画像が変更されたかどうかにかかわらず、ページが読み込まれるたびに、サーバー上のすべての画像のすべてのバージョンをキャッシュします。

Solution 2は役に立たない。nocacheヘッダーを画像ファイルに追加することは、実装するのが非常に難しいだけでなく、 事前に必要になる時期を予測する、考えている画像を初めて読み込むときmight将来のある時点での変更。

Etagsを入力...

絶対的な最良の方法これを解決することがわかったのは、ETAGS = imagesディレクトリの.htaccessファイル内。以下は、画像ファイルのヘッダーで一意のハッシュをブラウザに送信するようApacheに指示します。このハッシュは、画像ファイルが変更されたときにのみ変更され、この変更により、ブラウザは次に要求されたときに画像をリロードします。

<FilesMatch "\.(jpg|jpeg)$">
FileETag MTime Size
</FilesMatch>
12
cronoklee

JavaScriptを使用してブラウザで動的に実行する必要がある場合の例を次に示します...

<img id=graph alt="" 
  src="http://www.kitco.com/images/live/gold.gif" 
  />

<script language="javascript" type="text/javascript">
    var d = new Date(); 
    document.getElementById("graph").src = 
      "http://www.kitco.com/images/live/gold.gif?ver=" + 
       d.getTime();
</script>
10

私はすべての答えをチェックしましたが、最良のものはそうでした(そうではありません):

<img src="image.png?cache=none">

最初は。

ただし、cache = noneパラメーター(静的な「なし」のWord)を追加しても、何も影響はなく、ブラウザーはキャッシュからロードされます。

この問題の解決策は次のとおりです。

<img src="image.png?nocache=<?php echo time(); ?>">

基本的に、Unixタイムスタンプを追加してパラメータを動的にし、キャッシュを作成しない場合、機能しました。

しかし、私の問題は少し異なっていました:私はその場で生成されたPHPチャート画像をロードし、$ _ GETパラメータでページを制御していました。 URL GETパラメーターが同じ場合はキャッシュからイメージを読み取り、GETパラメーターが変更された場合はキャッシュしないようにしました。

この問題を解決するには、$ _ GETをハッシュする必要がありましたが、配列であるため、ここに解決策があります。

$chart_hash = md5(implode('-', $_GET));
echo "<img src='/images/mychart.png?hash=$chart_hash'>";

編集

上記のソリューションは問題なく機能しますが、ファイルが変更されるまでキャッシュバージョンを提供したい場合があります。 (上記のソリューションでは、そのイメージのキャッシュを完全に無効にします)したがって、ブラウザーからキャッシュされたイメージを提供するまで、イメージファイルの使用に変更があります。

echo "<img src='/images/mychart.png?hash=" . filemtime('mychart.png') . "'>";

filemtime()はファイルの変更時間を取得します。

9
Tarik

私はこのトピックが古いことを知っていますが、Googleで非常によくランク付けされています。これをヘッダーに入れるとうまくいくことがわかりました。

<meta Http-Equiv="Cache-Control" Content="no-cache">
<meta Http-Equiv="Pragma" Content="no-cache">
<meta Http-Equiv="Expires" Content="0">
<meta Http-Equiv="Pragma-directive: no-cache">
<meta Http-Equiv="Cache-directive: no-cache">
3
Dimitri Visser

画像ソースを変更することが解決策です。タイムスタンプまたは乱数を画像に追加することにより、実際にこれを行うことができます。

画像が表すデータなどのチェックサムを追加することをお勧めします。これにより、可能な場合にキャッシュが有効になります。

3

私はこれに対する解決策を探していましたが、私の場合は上記の答えがうまくいきませんでした(そして、それらについてコメントするには評判が不十分です)。少なくとも私のユースケースと私が使用しているブラウザ(OSX上のChrome)については、キャッシュを妨げると思われた唯一のものは次のとおりでした。

Cache-Control = 'no-store'

完全を期すために、「キャッシュなし、ストアなし、再検証が必要」の3つすべてを使用しています

したがって、私の場合(PythonでFlaskから動的に生成された画像を提供する場合)、できるだけ多くのブラウザーで動作することを期待して、次のことをしなければなりませんでした...

def make_uncached_response(inFile):
    response = make_response(inFile)
    response.headers['Pragma-Directive'] = 'no-cache'
    response.headers['Cache-Directive'] = 'no-cache'
    response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
    response.headers['Pragma'] = 'no-cache'
    response.headers['Expires'] = '0'
    return response
3
Mark

私はこの問題を抱えており、このように克服しています。

var newtags='<div class="addedimage"><h5>preview image</h5><img src="'+one+'?nocache='+Math.floor(Math.random() * 1000)+'"></div>';
1

これを使用して、同様の問題を解決しました...(外部プロバイダーからの)画像カウンターを表示します。常に正しく更新されませんでした。そして、ランダムパラメータが追加された後、すべてがうまく動作します:)

少なくとも毎分更新されるように、日付文字列を追加しました。

サンプルコード(PHP):

$output .= "<img src=\"http://xy.somecounter.com/?id=1234567890&".date(ymdHi)."\" alt=\"somecounter.com\" style=\"border:none;\">";

次のようなsrcリンクが作成されます。

http://xy.somecounter.com/?id=1234567890&1207241014
0
Pinoccio

別のソリューションを追加してみましょう。

最後に一意の文字列を追加することは完璧なソリューションです。

example.jpg?646413154

次のソリューションはこのメソッドを拡張し、キャッシュ機能と画像の更新時に新しいバージョンを取得することの両方を提供します。

イメージが更新されると、 filemtime が変更されます。

<?php
$filename = "path/to/images/example.jpg";
$filemtime = filemtime($filename);
?>

画像を出力します:

<img src="images/example.jpg?<?php echo $filemtime; ?>" >
0
Daniel

ハードコーディングされた画像URLがある場合、たとえば: http://example.com/image.jpg phpを使用して画像にヘッダーを追加できます。

まず、Apacheでjpgをphpとして処理する必要があります。こちらをご覧ください: 拡張子file.php.jpgでPHPを実行できますか?

ファイルから画像(imagecreatefromjpeg)を読み込み、前の回答からヘッダーを追加します。 php関数ヘッダーを使用してヘッダーを追加します。

次に、imagejpeg関数を使用して画像を出力します。

Phpでjpg画像を処理することは非常に安全ではないことに注意してください。また、このソリューションをテストしていないため、動作させるのはあなた次第です。

0
Sam Sam