缓存图片解决方案(来自stackoverflow)

来源:互联网 发布:pywin32 知乎 编辑:程序博客网 时间:2024/06/05 00:19

1)向URL中添加唯一的缓存清除查询参数,例如:

newImage.src = "image.jpg?t=" + new Date().getTime();

优点: 100%的可靠,快速和易于理解和执行。

缺点:绕过缓存完全,意味着不必要的延迟和带宽使用时图像视图间进行变换。将潜在地填充浏览器缓存(和任何中间缓存)与许多,许多副本完全相同的图像!此外,还需要修改图片网址。

当使用方法:使用时,图像是不断变化的,如用于现场摄像头饲料。如果您使用此方法,请务必与服务图像本身Cache-control: no-cache的HTTP头! (通常这可以使用.htaccess文件设置)。否则,你将逐渐填充高速缓存与旧版本的图像!


(2)向URL中添加查询参数,只有当文件发生更改时,才会更改,例如:

echo '<img src="image.jpg?m=' . filemtime('image.jpg') . '">';

(这是PHP的服务器端代码,但这里的重要的一点就是这样一个?M = [文件最后修改时间]查询字符串被附加到文件名)。

优点: 100%的可靠,快速和易于理解和实施,完美地保留缓存的优势。

缺点:需要修改图像的URL。此外,为服务器多一点工作 - 它必须获得文件最后修改的时间的访问。另外,需要服务器端信息,因此不适合纯客户端方案来检查刷新的映像。

使用时间:当你希望缓存图像,但可能需要在服务器端更新它们不时在不改变文件名本身。AND,当您可以轻松地确保正确的querystring添加到HTML中的每个图像实例。


(3)与头即成您的图像Cache-control: max-age=0, must-revalidate,以及独特添加的memcache -busting片段标识符的URL,如:

newImage.src = "image.jpg#" + new Date().getTime();

这里的想法是,缓存控制头将图像放在浏览器缓存中,但立即标记它们陈旧,以便每次重新显示时,浏览器都必须检查服务器以查看它们是否已更改。这确保了浏览器的HTTP缓存总是返回图像的最新副本。但是,如果浏览器有一个内存中的副本,那么浏览器通常会重复使用它,甚至在这种情况下甚至不检查它们的HTTP缓存。为了防止这种情况,一个片段标识符用于:在内存中的图象比较src的包括片段标识符,但它被查询HTTP缓存之前剥去。(因此,例如,image.jpg#Aimage.jpg#B可能既从显示image.jpg在浏览器的HTTP缓存条目,但image.jpg#B绝不会使用内存中显示从当保留的图象数据image.jpg#A最后被显示)。

优点:合理的利用的HTTP缓存机制,使用缓存图像,如果他们没有改变。适用于将查询字符串添加到静态图片网址的服务器(因为服务器从不会看到片段标识符 - 它们仅供浏览器自己使用)。

缺点:凭借浏览器(文件或至少很差)有点可疑的行为,就在他们的URL片段标识符图像(不过,我在FF27,Chrome33和IE11这个测试成功)。对于每个图像视图仍然发送重新验证请求到服务器,如果图像只有很少变化和/或延迟是一个大问题,这可能是过度的(因为您需要等待重新验证响应,即使缓存的图像仍然是好的) 。需要修改图片网址。

何时使用:使用时,图像可能会经常发生变化,或者需要由客户端刷新间歇性无服务器端脚本参与,但如果你仍然想缓存的优势。例如,轮询每几分钟不规律地更新图像的实况网络摄像头。或者,如果您的服务器不允许静态图片网址的查询字符串,请使用(1)或(2)。


(4)强行刷新使用Javascript特定的图像,首先加载到一个隐藏<iframe>,然后调用location.reload(true)的iframe的contentWindow

步骤是:

  • 将要刷新的图像加载到隐藏的iframe中。这只是一个设置步骤 - 如果需要,它可以提前实际刷新。如果图像在这个阶段无法加载甚至不重要!

  • 完成后,您的网页或任何DOM节点中的任何位置(即使在JavaScript变量中存储的页外)中的所有副本都会被清空。您需要确保所有:因为浏览器可能会以其他方式展示从陈旧的内存中拷贝图像(IE11尤其是做到这一点),这是必要的内存拷贝都被清零,刷新HTTP缓存之前。如果其他JavaScript代码以异步方式运行,您可能还需要阻止该代码在此期间创建待刷新图像的新副本。

  • 呼叫iframe.contentWindow.location.reload(true)true部队缓存旁路,直接从服务器重装并覆盖现有的缓存副本。

  • 一旦它完成重新 -loading,后立刻图像。他们现在应该从服务器显示新版本!

对于相同域的图片,您可以直接将图片加载到iframe中。对于跨域图像,你要代替加载HTML网页,从您的域名包含在图像<img>标记,否则你会得到尝试调用时错误“访问被拒绝” iframe.contentWindow.reload(...)

优点:工作就像image.reload()函数,你希望的DOM了!允许通过正常缓存图像(即使有未来的到期日期,如果你想要的话,从而避免频繁的重新验证)。允许您在不更改当前网页或其他网页(仅使用客户端代码)上的图片的网址的情况下刷新特定图片。

缺点:凭借的JavaScript。不是100%保证在每个浏览器正常工作(我已经测试这成功在FF27,Chrome33和IE11虽然)。相对于其他方法非常复杂。

何时使用:当你有,你想缓存基本上是静态图像的集合,但你仍然需要能够偶尔更新它们,并得到即时的视觉反馈,该更新发生。(特别是当只刷新整个浏览器页面不工作,例如在一些基于AJAX的web应用程序)。当方法(1) - (3)不可行,因为(无论什么原因)你不能更改可能显示图像的所有URL,你需要更新。(请注意,使用的3种方法,图像将被刷新,但如果另一个页面,然后尝试显示该图像没有相应的查询字符串或片段标识符,它可能会显示一个旧版本代替)。

0 0
原创粉丝点击