HTTP 缓存如何在 asp mvc 4 中工作
How HTTP caching works in asp mvc 4
我有一个控制器 returns SVG images.As 我想有好的表现,我决定使用 Caching.
根据我在网上看到的内容,一旦你用 HttpContext.Response.Cache.SetLastModified(date)
设置了最后修改日期
您可以使用 HttpContext.Request.Headers.Get("If-Modified-Since")
从浏览器请求它。比较两个日期。如果它们相等,则表示图像未被修改,因此可以 return 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" return,实际上函数 HttpContext.Request.Headers.Get("If-Modified-Since")
准确地重新调整图像从上一个 returned 的时间呼叫 return new FileContentResult(Resources.getsvg(id), "image/svg+xml");
.
所以我的问题是,
1 - 函数 HttpContext.Response.Cache.SetLastModified(lastModifiedDate)
的具体设置是什么?
2 - 我(服务器)如何通过浏览器设置 "If-Modified-Since" return?
看来您在这里混淆了一堆相关但仍然完全不同的概念。
OutputCache
是服务器上的 memory-based 缓存。在那里缓存一些东西意味着虽然它仍然存在于内存中并且还没有过时,但服务器可以放弃处理该操作并返回之前已经呈现的响应。客户完全不参与。
HTTP缓存是服务器和客户端之间的一种交互。服务器发送 Last-Modified
响应 header,向客户端指示上次更新资源的时间。客户端发送一个 If-Modified-Since
request header,向服务器表明如果资源还没有被发送,则没有必要将资源作为响应的一部分发送修改的。所有这一切都是为了节省一点带宽。仍然发出请求并且仍然收到响应,但资源的实际数据(如您的 SVG)不必通过管道传输。
然后,基本 browser-based 缓存与 HTTP 缓存协同工作,但没有它也能正常工作。浏览器只是保存它下载的每个资源的副本。如果它仍然有那个副本,它就不会费心向服务器发出再次获取它的请求。在这种情况下,甚至可能不会提出请求。但是,浏览器也可能会发送带有 If-Modified-Since
header 的请求,以查看它拥有的文件是否仍然是 "fresh"。然后,如果它没有再次从服务器获取文件,它就使用它保存的副本。
无论哪种方式,都在客户端。客户端可以配置为从不缓存,在这种情况下,它将始终请求资源,无论它们是否已被修改,或者它可以配置为始终使用缓存,甚至从不费心检查资源是否已更新或没有。
还有诸如代理之类的东西使事情变得更加复杂,因为代理充当客户端并且可以在网络浏览器或 end-user 的其他客户端甚至获取之前随意选择缓存或不缓存对此事有发言权。
归根结底就是你不能在服务器上设置If-Modified-Since
,你不能控制客户端是否在请求中发送它。当谈到涉及客户端的缓存形式时,您会随心所欲。
我有一个控制器 returns SVG images.As 我想有好的表现,我决定使用 Caching.
根据我在网上看到的内容,一旦你用 HttpContext.Response.Cache.SetLastModified(date)
设置了最后修改日期
您可以使用 HttpContext.Request.Headers.Get("If-Modified-Since")
从浏览器请求它。比较两个日期。如果它们相等,则表示图像未被修改,因此可以 return 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" return,实际上函数 HttpContext.Request.Headers.Get("If-Modified-Since")
准确地重新调整图像从上一个 returned 的时间呼叫 return new FileContentResult(Resources.getsvg(id), "image/svg+xml");
.
所以我的问题是,
1 - 函数 HttpContext.Response.Cache.SetLastModified(lastModifiedDate)
的具体设置是什么?
2 - 我(服务器)如何通过浏览器设置 "If-Modified-Since" return?
看来您在这里混淆了一堆相关但仍然完全不同的概念。
OutputCache
是服务器上的 memory-based 缓存。在那里缓存一些东西意味着虽然它仍然存在于内存中并且还没有过时,但服务器可以放弃处理该操作并返回之前已经呈现的响应。客户完全不参与。
HTTP缓存是服务器和客户端之间的一种交互。服务器发送 Last-Modified
响应 header,向客户端指示上次更新资源的时间。客户端发送一个 If-Modified-Since
request header,向服务器表明如果资源还没有被发送,则没有必要将资源作为响应的一部分发送修改的。所有这一切都是为了节省一点带宽。仍然发出请求并且仍然收到响应,但资源的实际数据(如您的 SVG)不必通过管道传输。
然后,基本 browser-based 缓存与 HTTP 缓存协同工作,但没有它也能正常工作。浏览器只是保存它下载的每个资源的副本。如果它仍然有那个副本,它就不会费心向服务器发出再次获取它的请求。在这种情况下,甚至可能不会提出请求。但是,浏览器也可能会发送带有 If-Modified-Since
header 的请求,以查看它拥有的文件是否仍然是 "fresh"。然后,如果它没有再次从服务器获取文件,它就使用它保存的副本。
无论哪种方式,都在客户端。客户端可以配置为从不缓存,在这种情况下,它将始终请求资源,无论它们是否已被修改,或者它可以配置为始终使用缓存,甚至从不费心检查资源是否已更新或没有。
还有诸如代理之类的东西使事情变得更加复杂,因为代理充当客户端并且可以在网络浏览器或 end-user 的其他客户端甚至获取之前随意选择缓存或不缓存对此事有发言权。
归根结底就是你不能在服务器上设置If-Modified-Since
,你不能控制客户端是否在请求中发送它。当谈到涉及客户端的缓存形式时,您会随心所欲。