【问题标题】:How HTTP caching works in asp mvc 4HTTP 缓存如何在 asp mvc 4 中工作
【发布时间】:2016-02-03 15:49:38
【问题描述】:

我有一个返回 SVG 图像的控制器。由于我想获得良好的性能,我决定使用 缓存

根据我在网上阅读的内容,一旦您将上次修改日期设置为 HttpContext.Response.Cache.SetLastModified(date) 您可以使用HttpContext.Request.Headers.Get("If-Modified-Since") 从浏览器请求它。比较两个日期。如果它们相等,则表示图像没有被修改,因此您可以返回HttpStatusCodeResult(304, "Not Modified")

但是发生了一些奇怪的事情,这是我的代码:

[OutputCache(Duration = 60, Location = OutputCacheLocation.Any, VaryByParam = "id")]
   public ActionResult GetSVGResources(string id)
    {

        DateTime lastModifiedDate = Assembly.GetAssembly(typeof(Resources)).GetLinkerTime();

        string rawIfModifiedSince = HttpContext.Request.Headers.Get("If-Modified-Since");

        if (string.IsNullOrEmpty(rawIfModifiedSince))
        {
            // Set Last Modified time
            HttpContext.Response.Cache.SetLastModified(lastModifiedDate);
        }
       else
        {
            DateTime ifModifiedSince = DateTime.Parse(rawIfModifiedSince);

            if (DateTime.Compare(lastModifiedDate, ifModifiedSince) == 0)
            {
                // The requested file has not changed
                return new HttpStatusCodeResult(304, "Not Modified");
            }

        }

        if (!id.Equals("null"))
            return new FileContentResult(Resources.getsvg(id), "image/svg+xml");
        else
           return null;
    }

正在发生的是函数 HttpContext.Response.Cache.SetLastModified(lastModifiedDate);没有设置浏览器返回的“If-Modified-Since”,实际上HttpContext.Request.Headers.Get("If-Modified-Since")函数返回的正是上一次调用return new FileContentResult(Resources.getsvg(id), "image/svg+xml");返回图像的时间。

所以我的问题是,

1 - 函数HttpContext.Response.Cache.SetLastModified(lastModifiedDate) 究竟设置了什么?

2 - 我(服务器)如​​何设置浏览器返回的“If-Modified-Since”?

【问题讨论】:

    标签: asp.net-mvc-4 http-headers browser-cache cache-control outputcache


    【解决方案1】:

    您似乎在这里混淆了一堆相关但完全不同的概念。

    OutputCache 是服务器上基于内存的缓存。在那里缓存一些东西意味着虽然它仍然存在于内存中并且尚未陈旧,但服务器可以放弃处理该操作并仅返回之前已经呈现的响应。客户根本不参与。

    HTTP 缓存是服务器和客户端之间的交互。服务器发送Last-Modifiedresponse 标头,向客户端指示资源上次更新的时间。客户端发送一个If-Modified-Since request 标头,向服务器指示如果资源没有被修改,则不需要将其作为响应的一部分发送。所有这一切都节省了一点带宽。请求仍会发出并仍会收到响应,但资源的实际数据(如您的 SVG)不必沿管道传输。

    然后,基于浏览器的基本缓存与 HTTP 缓存协同工作,但没有它也能正常工作。浏览器只是保存它下载的每个资源的副本。如果它仍然有那个副本,它不会费心向服务器发出再次获取它的请求。在这种情况下,甚至可能不会发出请求。但是,浏览器也可以发送带有If-Modified-Since 标头的请求,以查看它拥有的文件是否仍然“新鲜”。然后,如果它没有再次从服务器获取文件,它只会使用其保存的副本。

    不管怎样,一切都在客户端。客户端可以配置为从不缓存,在这种情况下,无论资源是否已被修改,它都将始终请求资源,或者可以将其配置为始终使用缓存,甚至从不费心检查资源是否已更新或不是。

    还有诸如代理之类的东西使事情变得更加复杂,因为代理充当客户端并且可以在网络浏览器或最终用户的其他客户端甚至获得发言权之前随意选择缓存或不缓存问题。

    归结为你不能在服务器上设置If-Modified-Since,你也不能控制客户端是否在请求中发送它。当涉及到涉及客户端的缓存形式时,您会随心所欲。

    【讨论】:

    • 有趣,我不知道“outputcache”是否是服务器端基于内存的缓存。但是如何检查是否需要返回图像?因为“If-Modified-Since”返回的时间不是上次修改图像的时间。
    猜你喜欢
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多