禁用某些图像的缓存

时间:2009-04-08 05:30:20

标签: html image caching

我使用PHP库生成一些图像。

有时浏览器不会加载新生成的文件。

如何为我动态创建的图像禁用缓存?

注意:随着时间的推移,我必须为创建的图像使用相同的名称。

13 个答案:

答案 0 :(得分:198)

这个问题的一个常见而简单的解决方案是感觉像黑客但相当便携,就是为每个动态图像请求添加一个随机生成的查询字符串。

所以,例如 -

<img src="image.png" />

会变成

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

或者

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

从Web服务器的角度来看,访问相同的文件,但从浏览器的角度来看,不能执行缓存。

随机数生成可以在服务页面时在服务器上发生(只是确保页面本身不被缓存...),或者在客户端上(使用JavaScript)。

您需要验证您的网络服务器是否可以应对此技巧。

答案 1 :(得分:39)

浏览器缓存策略可以通过HTTP标头控制。请记住,它们只是一个暗示,真的。由于浏览器在此(以及任何其他)字段中非常不一致,因此您需要多个标头才能在一系列浏览器上获得所需的效果。

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

答案 2 :(得分:11)

解决方案1不是很好。它确实有效,但在图像文件的末尾添加hacky随机或带时间戳的查询字符串是不可扩展的,并且会使浏览器重新下载并缓存每个版本的您发送的每张图片。

解决方案2没用。向图像文件添加<FilesMatch "\.(jpg|jpeg)$"> FileETag MTime Size </FilesMatch> 标头不仅非常难以实现,而且完全不切实际,因为它要求预测它何时会需要提前,这是您第一次加载任何您认为 可能 的图片在将来某个时候发生变化。

输入Etags ...

绝对最佳方式我发现解决此问题的方法是在images目录中的.htaccess 文件中使用 ETAGS。以下内容告诉Apache在映像文件头中向浏览器发送唯一的哈希值。只有在修改映像文件时才会更改此哈希值,此更改会在下次请求时触发浏览器重新加载映像。

<a class="clicker reveal" style="background-color: #81d742; border: 0px; font-size: 12px; text-decoration: none;">MORE INFOS</a>

答案 3 :(得分:10)

如果您需要使用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>

答案 4 :(得分:9)

我检查了所有答案,最好的答案似乎是(不是):

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

起初。

但是,如果你添加 cache = none 参数(这是静态的&#34;无&#34;字),它不起作用,浏览器仍然从缓存加载。< / p>

解决这个问题的方法是:

<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'>";

修改

虽然上面的解决方案运行正常,但有时您希望提供缓存版本UNTIL文件已更改。 (使用上面的解决方案,它会完全禁用该图像的缓存) 因此,要从浏览器UNTIL提供缓存图像,图像文件的使用会发生变化:

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

filemtime()获取文件修改时间。

答案 5 :(得分:3)

我知道这个话题很老,但在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">

答案 6 :(得分:3)

更改图像源是解决方案。您确实可以通过向图像添加时间戳或随机数来实现此目的。

最好是添加一个校验和,例如图像所代表的数据。这样可以在可能的情况下启用缓存。

答案 7 :(得分:2)

我只是在寻找解决方案,上面的答案在我的案例中不起作用(我没有足够的声誉来评论它们)。事实证明,至少对于我的用例和我使用的浏览器(Chrome OSX),似乎唯一阻止缓存的是:

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

答案 8 :(得分:1)

我有这个问题,并且像这样克服。

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

答案 9 :(得分:0)

我用它来解决我的类似问题...显示图像计数器(来自外部提供商)。它没有始终正确刷新。添加随机参数后,一切正常:)

我附加了一个日期字符串,以确保至少每分钟刷新一次。

示例代码(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

答案 10 :(得分:0)

如果你有一个硬编码的图片网址,例如:http://example.com/image.jpg,你可以使用php为图片添加标题。

首先,你必须让apache处理你的jpg作为php。 看这里: Is it possible to execute PHP with extension file.php.jpg?

从文件加载图像(imagecreatefromjpeg),然后添加先前答案的标题。使用php函数标题添加标题。

然后使用imagejpeg函数输出图像。

请注意,让php处理jpg图像非常不安全。另外请注意,我没有测试过这个解决方案,所以由你决定是否正常工作。

答案 11 :(得分:0)

让我们再添一个解决方案。

最后添加一个唯一的字符串是一个完美的解决方案。

example.jpg?646413154

以下解决方案扩展了此方法并提供了缓存功能,并在更新映像时获取新版本。

更新图片后,filemtime将会更改。

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

现在输出图片:

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

答案 12 :(得分:-1)

简单,发送一个标题位置。

我的网站,包含一张图片,上传图片后,没有更改,然后我添加此代码:

<?php header("Location: pagelocalimage.php"); ?>

为我工作。