【问题标题】:What is the relationship between http cache in browser and http status 304?浏览器中的http缓存和http状态304是什么关系?
【发布时间】: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.htmlindex2.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


【解决方案1】:

根据服务器对aaa.js 的第一次请求的响应,浏览器可能会也可能不会再次请求该文件。

如果服务器没有随文件发送特定的缓存标头,则在第二个页面加载时,浏览器将再次发送aaa.js 的请求。如果浏览器的缓存中没有 JS 文件,它会像第一次一样发送请求。如果aaa.js 在浏览器缓存中,它将向服务器发送一个请求,该请求包含一个If-Modified-Since 标头以及文件先前下载的日期。服务器然后检查文件是否已被修改:如果是,则发送新文件;否则发送 304 标头。

现在让我们回到开头。在对aaa.js 的初始请求中,服务器可以包含一个Cache-control 标头,告诉浏览器缓存文件多长时间。假设Cache-control: max-age=3600 指示将文件缓存一小时(3600 秒)。

如果用户在一小时内访问第二个页面,浏览器甚至不会向服务器发送aaa.js的请求,它只会毫无疑问地使用缓存的文件。 p>

时间一到并加载了新页面,浏览器就会再次请求aaa.js

【讨论】:

    猜你喜欢
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    相关资源
    最近更新 更多