2010-05-20 101 views
1

假设一个简单的aspx数据输入页面,其中admin用户可以上传图像以及其他一些数据。它们存储在数据库中,下一次管理访问该页面以编辑记录,获取图像数据并生成预览并保存到磁盘(使用GDI +),预览显示在图像控件中。如何强制客户端浏览器从服务器下载图像而不是使用其缓存

此过程首次正常工作,但如果图像发生变化(上传一个新图像),下一次浏览页面时会显示之前上传的图像。我调试了应用程序,一切正常。新图像数据在数据库中,新预览存储在临时位置,但页面显示前一个。如果我刷新页面,它会显示新的图像预览。我应该提到预览总是以一个名字(每个记录的ID作为名字)保存到磁盘。

我认为这是因为IE和其他浏览器使用客户端缓存,而不是每次页面冲浪时加载图像。我想知道是否有办法强制客户端浏览器自行刷新,以便在没有用户干预的情况下显示新上传的图像。

感谢和赞赏提前,

+0

这些建议是否符合您的需求? – jasonmp85 2010-06-03 10:09:00

回答

3

最简单的方法就是让你的应用程序每次上传新的图片时间改变图像的文件名。

也许通过追加日期或日期和时间到图像文件名的末尾。

或者,你可以尝试在HTML报头中设置缓存控制:<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">

+0

+1这种方法在过去对我来说很有效。特别是,当发布新版本的网站与新的图像。我们在图片的网址中加入了版本号。在你的情况下,你应该想出一种方法来逐个图像地增加一个版本。一个可爱的小字符串解析练习可能。需要注意的是,这种方法在CSS样式表中引用的任何图像都不能很好地工作,但在这种情况下,这不会影响您。 – 2010-05-20 09:49:28

+0

另一件事。请注意,@ Gilbert的答案是两部分答案:更改文件名或设置缓存控制。我主张第一部分,改变文件名,但不改变第二部分“NO-CACHE”,因为后者意味着当图像没有改变时,你会失去客户端缓存的好处。 – 2010-05-20 09:52:28

0

The HTTP Spec包含用于传达关于资源的“可缓存”,以客户的各种信息标题。维基百科也有一个很好的总结here

基本上,当一台服务器向客户端传递一些资源时,它会附带各种元数据。基于这个元数据,客户决定是否缓存资源,如果是,缓存多久。

你可以用各种方式解决你的问题。最简单的方法可能是始终将图像响应中的Expires标题设置为1970年1月1日的值(Unix Epoch)。这将告诉客户端在1970年过期缓存条目。由于它总是在1970年以后,客户端永远不会缓存资源并且总是要求一个新的副本。

这种方法确实有其不足之处,即如果图像永不改变,您不必要地承担额外的带宽和服务器上的负载。这就是ETag和LastModified标头进来的地方。

服务器可以计算每个资源的短散列。假设一个图像的哈希值为a423fedc。客户端将存储此散列,并在第二次请求资源时,使用If-None-Match请求标头将其提供给服务器。如果服务器计算出该资源的ETag未更改,则它只会发送一个304 Not Modified,客户端可以使用该缓存版本。 ETags进一步解释here

但我认为你的情况最好的解决方案是Last-Modified标题。服务器将发送与上次修改图像相对应的日期。在重新加载页面后,客户端将此日期作为If-Modified-Since标题的一部分发回。如果自该日期以后该图像已被修改,则服务器将发送更新的图像。如果没有,则发回304 Not Modified代码。

我不是ASP开发人员,所以我不能告诉你如何在你的响应中设置这些标题,但如果你能弄明白,每个浏览器都会正确地进行缓存。我确实找到this article,看起来它可以告诉你如何在ASP-land中做到这一点,但只是知道标题应该足以让你开始。

对于调试,最好使用Firebug插件等Firefox浏览器进行测试。它可以向您显示您的请求和回复中的标题,以便您知道实际上正在通过的线路。如果您使用的是缓存版本,或者服务器没有返回新数据,您实际上会在Firebug中看到304响应,这很有用。

相关问题