【发布时间】:2013-02-01 13:56:11
【问题描述】:
已编辑
我想在客户端缓存图片,并且知道在mvc 3中有不同的方法可以做到:(如果我错了,请纠正我)
1) 您可以使用OutputCacheAttribute,它在Expires http 标头的帮助下工作。但它会返回304 Not Modified,除非时间到期(即使图像已更改)。
2) 为避免显示陈旧图像,您可以使用Last-Modified http 标头(带有OutputCacheAttribute)。在这种情况下,浏览器将带有If-Modified-Since http 标头的请求发送到服务器。在服务器上,您验证对象是否仍然有效,如果是,您只需返回 Last-Modified http 标头(浏览器从本地缓存中获取图像);如果对象已被修改,则返回 200 OK 状态。
因此,浏览器每次从自己的缓存中获取图像之前都需要向服务器发送请求。 Here is the example -
3) 还有另一种方法(在我的情况下,我被告知正确的方法,因为图像很少会改变......无论如何,我需要完全实现这一点):将修改日期添加到图像 url 和使用Expires 为永恒(1 年或更长时间)设置缓存。如果图像已更改,您应该发送带有新版本的新网址。
代码如下:
public class LastModifiedCacheAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Result is FilePathResult)
{
var result = (FilePathResult)filterContext.Result;
var lastModify = File.GetLastWriteTime(result.FileName);
if (!HasModification(filterContext.RequestContext, lastModify))
filterContext.Result = NotModified(filterContext.RequestContext, lastModify);
SetLastModifiedDate(filterContext.RequestContext, lastModify);
}
base.OnActionExecuted(filterContext);
}
private static void SetLastModifiedDate(RequestContext requestContext, DateTime modificationDate)
{
requestContext.HttpContext.Response.Cache.SetLastModified(modificationDate);
}
private static bool HasModification(RequestContext context, DateTime modificationDate)
{
var headerValue = context.HttpContext.Request.Headers["If-Modified-Since"];
if (headerValue == null)
return true;
var modifiedSince = DateTime.Parse(headerValue).ToLocalTime();
return modifiedSince < modificationDate;
}
private static ActionResult NotModified(RequestContext response, DateTime lastModificationDate)
{
response.HttpContext.Response.Cache.SetLastModified(lastModificationDate);
return new HttpStatusCodeResult(304, "Page has not been modified");
}
}
我在 Global.asax 中注册了LastModifiedCacheAttribute,并将以下 OutputCacheAttribute 应用于我的操作方法。
[HttpGet, OutputCache(Duration = 3600, Location = OutputCacheLocation.Client, VaryByParam = "productId")]
public FilePathResult GetImage(int productId)
{ // some code }
如果我使用上面的代码,浏览器似乎不会向服务器发送请求,而是只会从缓存中获取图像,除非持续时间没有结束。 (当我更改图像时,浏览器不显示新版本)
问题:
1) 如何实现第三种方法,使浏览器从客户端缓存中获取图像(并且不会在每次需要图像时向服务器发送响应),除非图像被修改了吗?
已编辑:实际代码将不胜感激。
2) 在上面的代码中,第一个图像请求的时间被写入Last-Modified(不知道为什么)。如何将文件的修改日期写入 Last-Modified?
edited: 这个问题与第二种方法有关。此外,如果我仅在客户端缓存并使用Last-Modified 实现,则只有在按下F5 时才会获得304 Not Modified 状态。如果我重新输入相同的网址,我将得到200 OK。如果我在不使用Last-Modified 的情况下缓存在客户端上,无论如何它都会返回200 OK。这怎么解释?
【问题讨论】:
标签: asp.net asp.net-mvc asp.net-mvc-3 caching browser-cache