【发布时间】:2014-12-27 08:13:38
【问题描述】:
在 ASP.NET MVC 中,现在我们可以向浏览器响应 304 代码,这意味着服务器中的内容没有被改变,浏览器可以使用它的本地缓存来处理这个 url。
public ActionResult Image(int id){
var image = _imageRepository.Get(id);
if (image == null)
throw new HttpException(404, "Image not found");
if (!String.IsNullOrEmpty(Request.Headers["If-Modified-Since"]))
{
CultureInfo provider = CultureInfo.InvariantCulture;
var lastMod = DateTime.ParseExact(Request.Headers["If-Modified-Since"], "r", provider).ToLocalTime();
if (lastMod == image.TimeStamp.AddMilliseconds(-image.TimeStamp.Millisecond))
{
Response.StatusCode = 304;
Response.StatusDescription = "Not Modified";
return Content(String.Empty);
}
}
var stream = new MemoryStream(image.GetImage());
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetLastModified(image.TimeStamp);
return File(stream, image.MimeType);
}
但是我对浏览器中的逻辑有点困惑。例如,当我们第一次请求页面时,http://www.test.com/index.html,it 会加载一个 javascript 文件 aaa.js。但是当浏览器询问另一个页面http://www.test.com/index2.html时,这个页面也包含aaa.js。
问题来了。我们知道浏览器有一个http缓存的逻辑。我假设当浏览器请求 index2.html 时,它会检查它在本地是否有可用的 aaa.js,因此它不会与服务器就该文件进行通信。所以这里没有返回 304,因为浏览器没有请求任何关于这个文件的信息。这是正确的逻辑吗?
或者每次它都会与服务器通信来检查文件的版本?在这种情况下,如果我们不写任何 C# 代码返回 304 状态,每次都会返回整个文件。所以我猜这不是逻辑。
浏览器缓存和304状态有什么关系?
【问题讨论】:
-
对于页面的每个链接资产,例如JS文件和CSS文件,都有一个请求和响应。因此,如果有 aaa.js 的 304 响应,浏览器将使用
aaa.js的缓存副本,而不管index.html或index2.html的响应是什么。 -
问题是,当浏览器请求 index2.html 时,它会尝试向服务器发送请求,还是直接使用本地缓存?如果它会向服务器发送请求,但我们没有编写任何 C# 代码返回 304,所以它会再次返回整个 aaa.js 文件。
-
当您加载 index2.html 时,浏览器将向服务器发出包含“if-modified-since”标头的请求。此元数据指定浏览器缓存的页面副本的使用时间。服务器可以使用它来决定是否需要提供新副本(在这种情况下,您会收到带有新内容的 200 响应),或者浏览器的缓存副本是否足够(在这种情况下返回 304,并且浏览器将仅使用其缓存的页面副本)。请注意,这整个事务与 aaa.js 无关,我们只是在谈论 index2.html。
-
我所描述的只是 加载 HTML 文档 index2.html 的事件序列。浏览器解析 HTML 后,根据链接的资产,它可能会对 JS 文件、CSS 文件甚至更多 HTML 文件发出更多请求。对于这些请求中的每一个,都会发生类似的事件序列。例如。从缓存或服务器加载 index2.html 后,浏览器会注意到有一个 script 标签指向 aaa.js。现在它将向服务器发出 aaa.js 请求,以及我之前描述的相同 if-modified-since 标头。
-
您好 Asad,非常感谢您的回复。浏览器解析了 index2.html 的 HTML,它注意到有一个链接到 aaa.js 的标签。正如你所说,所以它会向服务器发送一个请求来接收这个文件。但是如果在服务器端,我们还没有编写任何代码来检查“if-modified-since”。 Web 应用程序只是简单地返回 aaa.js 文件。所以这里浏览器永远不会在本地使用本地缓存?
标签: c# browser-cache