已编辑

我想在客户端缓存图像,并且知道在 mvc 3 中有不同的方法可以做到这一点:(如果我错了,请纠正我)

1) 您可以使用 OutputCacheAttribute,它在 Expires http header 的帮助下工作。但它会返回 304 Not Modified 除非时间到期(即使图像已更改)。

2) 避免显示过时的图像您可以使用 Last-Modified http header (使用 OutputCacheAttribute )。在这种情况下,浏览器使用 If-Modified-Since http header 将请求发送到服务器。在服务器上,您验证对象是否仍然有效,如果是,您只需返回 Last-Modified http header (浏览器从本地缓存中获取图像);如果对象被修改,则返回 200 OK 状态。
因此,浏览器每次都需要将请求发送到服务器,然后才能从自己的缓存中获取图像。 Here is the example -

3)还有另一种方式(正如我在我的情况下被告知正确的方式,导致图像很少改变......无论如何,我需要完全实现这一点):将修改日期添加到图像url并设置缓存Expires 为永恒(1 年或更长时间)。如果图像已更改,您应该使用新版本发送新 url。

这是代码:

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?
编辑: 这个问题与第二种方法有关。此外,如果我仅在客户端缓存并使用 Last-Modified 实现,则只有按 304 Not Modified 才会获得 F5 状态。如果我重新输入相同的网址,我会得到 200 OK 。如果我在不使用 Last-Modified 的情况下缓存在客户端上,无论如何它将始终返回 200 OK。这怎么解释?

最佳答案

您可以考虑使用 ETags ( http://en.wikipedia.org/wiki/HTTP_ETag ),这是我阅读您的问题时想到的第一件事。

你也可以看看这里:Set ETag for FileResult - MVC 3

关于asp.net - 在 asp.net mvc 3 中使用 Last-Modified header 和 OutputCacheAttribute 的客户端缓存,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14914228/

10-11 12:02