我使用PHP库生成一些图像。
有时浏览器不会加载新生成的文件。
如何为我动态创建的图像禁用缓存?
注意:随着时间的推移,我必须为创建的图像使用相同的名称。
答案 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>
标头不仅非常难以实现,而且完全不切实际,因为它要求预测它何时会需要提前,这是您第一次加载任何您认为 可能 的图片在将来某个时候发生变化。
绝对最佳方式我发现解决此问题的方法是在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"); ?>
为我工作。