Phi*_*sse 115 html caching image image-caching browser-cache
我正在为两个无偿网站编写和使用一个非常简单的基于CGI(Perl)的内容管理工具.它为网站管理员提供HTML表单,用于填写字段(日期,地点,标题,描述,链接等)的事件并保存.在该表单上,我允许管理员上传与事件相关的图像.在显示表单的HTML页面上,我还显示了上传图片的预览(HTML img标签).
当管理员想要更改图片时,会发生此问题.他只需点击"浏览"按钮,选择一张新照片然后按确定即可.这很好用.
上传图像后,我的后端CGI处理上传并正确地重新加载表单.
问题是显示的图像没有刷新.即使数据库保存正确的图像,仍会显示旧图像.我已将其缩小到图像在Web浏览器中缓存的事实.如果管理员点击Firefox /资源管理器/ Safari中的RELOAD按钮,则所有内容都会刷新,并且只会显示新图像.
我试图通过写一个过去很远的日期的HTTP Expires指令来控制缓存.
Expires: Mon, 15 Sep 2003 1:00:00 GMT
Run Code Online (Sandbox Code Playgroud)
请记住,我在管理方面,我并不关心页面是否需要更长时间才能加载,因为它们总是过期.
但是,这也不起作用.
上传图像时,其文件名不会保留在数据库中.它被重命名为Image.jpg(在使用时简单地说出来).使用新图像替换现有图像时,名称也不会更改.只是图像文件的内容发生了变化.
网络服务器由托管服务/ ISP提供.它使用Apache.
有没有办法强制Web浏览器不缓存此页面中的内容,甚至图像?
我正在使用数据库实际"保存文件名"的选项.这样,如果图像被更改,IMG标签的src也将改变.但是,这需要在整个站点进行大量更改,如果我有更好的解决方案,我宁愿不这样做.此外,如果上传的新图像具有相同的名称(例如图像有点照片并重新上传),这仍然无效.
epo*_*olf 174
Armin Ronacher有正确的想法.问题是随机字符串可能会发生冲突.我会用:
<img src="picture.jpg?1222259157.415" alt="">
Run Code Online (Sandbox Code Playgroud)
其中"1222259157.415"是服务器上的当前时间.(注意:我使用python的time.time()来生成)
Arm*_*her 45
简单修复:将随机查询字符串附加到图像:
<img src="foo.cgi?random=323527528432525.24234" alt="">
Run Code Online (Sandbox Code Playgroud)
HTTP RFC说的是什么:
Cache-Control: no-cache
Run Code Online (Sandbox Code Playgroud)
但那不是很好:)
小智 18
我使用PHP的文件修改时间函数,例如:
echo <img src='Images/image.png?" . filemtime('Images/image.png') . "' />";
Run Code Online (Sandbox Code Playgroud)
如果更改图像,则使用新图像而不是缓存图像,因为具有不同的修改时间戳.
x-y*_*uri 15
我会用:
<img src="picture.jpg?20130910043254">
Run Code Online (Sandbox Code Playgroud)
其中"20130910043254"是文件的修改时间.
上传图像时,其文件名不会保留在数据库中.它被重命名为Image.jpg(在使用时简单地说出来).使用新图像替换现有图像时,名称也不会更改.只是图像文件的内容发生了变化.
我认为有两种类型的简单解决方案:1)首先想到的解决方案(直截了当的解决方案,因为它们很容易想出来),2)你在思考之后最终得到的解决方案(因为它们很容易使用).显然,如果你选择考虑事情,你不会总是受益.但我相信,第二种选择被低估了.试想为什么php
如此受欢迎;)
小智 7
您可以编写一个代理脚本来提供图像 - 虽然这有点多了.有点喜欢这个:
HTML:
<img src="image.php?img=imageFile.jpg&some-random-number-262376" />
Run Code Online (Sandbox Code Playgroud)
脚本:
// PHP
if( isset( $_GET['img'] ) && is_file( IMG_PATH . $_GET['img'] ) ) {
// read contents
$f = open( IMG_PATH . $_GET['img'] );
$img = $f.read();
$f.close();
// no-cache headers - complete set
// these copied from [php.net/header][1], tested myself - works
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Some time in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
// image related headers
header('Accept-Ranges: bytes');
header('Content-Length: '.strlen( $img )); // How many bytes we're going to send
header('Content-Type: image/jpeg'); // or image/png etc
// actual image
echo $img;
exit();
}
Run Code Online (Sandbox Code Playgroud)
实际上,图像src上的无缓存标头或随机数应该足够了,但是因为我们想要防弹..
小智 7
使用Class =“ NO-CACHE”
范例html:
<div>
<img class="NO-CACHE" src="images/img1.jpg" />
<img class="NO-CACHE" src="images/imgLogo.jpg" />
</div>
Run Code Online (Sandbox Code Playgroud)
jQuery的:
$(document).ready(function ()
{
$('.NO-CACHE').attr('src',function () { return $(this).attr('src') + "?a=" + Math.random() });
});
Run Code Online (Sandbox Code Playgroud)
javascript:
var nods = document.getElementsByClassName('NO-CACHE');
for (var i = 0; i < nods.length; i++)
{
nods[i].attributes['src'].value += "?a=" + Math.random();
}
Run Code Online (Sandbox Code Playgroud)
结果:src =“ images / img1.jpg” => src =“ images / img1.jpg?a = 0.08749723793963926”
小智 6
我是一个新的编码器,但这是我想出来的,阻止浏览器缓存并保持我的网络摄像头视图:
<meta Http-Equiv="Cache" content="no-cache">
<meta Http-Equiv="Pragma-Control" content="no-cache">
<meta Http-Equiv="Cache-directive" Content="no-cache">
<meta Http-Equiv="Pragma-directive" Content="no-cache">
<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">
Run Code Online (Sandbox Code Playgroud)
不知道什么在什么浏览器上工作,但它确实适用于某些人:IE:当网页刷新和网站重新访问时(无需刷新).CHROME:仅在刷新网页时才有效(即使在重新访问后).SAFARI和iPad:不起作用,我必须清除历史和Web数据.
关于SAFARI/iPad的任何想法?
我检查了网络上的所有答案,最好的一个似乎是:(实际上不是)
<img src="image.png?cache=none">
Run Code Online (Sandbox Code Playgroud)
首先。
但是,如果您添加cache=none参数(这是静态的“无”字),则不会产生任何影响,浏览器仍会从缓存中加载。
这个问题的解决方法是:
<img src="image.png?nocache=<?php echo time(); ?>">
Run Code Online (Sandbox Code Playgroud)
您基本上添加了 unix 时间戳以使参数动态且没有缓存,它起作用了。
但是,我的问题有点不同:我正在加载动态生成的 php 图表图像,并使用 $_GET 参数控制页面。我希望在 URL GET 参数保持不变时从缓存中读取图像,并且在 GET 参数更改时不缓存。
为了解决这个问题,我需要散列 $_GET 但因为它是数组,所以这里是解决方案:
$chart_hash = md5(implode('-', $_GET));
echo "<img src='/images/mychart.png?hash=$chart_hash'>";
Run Code Online (Sandbox Code Playgroud)
编辑:
虽然上述解决方案工作得很好,但有时您希望提供缓存版本,直到文件被更改。(使用上述解决方案,它会完全禁用该图像的缓存)因此,要从浏览器提供缓存图像,直到图像文件使用发生变化:
echo "<img src='/images/mychart.png?hash=" . filemtime('mychart.png') . "'>";
Run Code Online (Sandbox Code Playgroud)
filemtime() 获取文件修改时间。