如何判断XMLHTTPRequest是否命中浏览器缓存

36

在 JavaScript 执行的过程中,是否有可能判断 GET XMLHTTPRequest 是否从浏览器缓存获取响应而不是从服务器获取?

6个回答

24
XMLHttpRequest规范中可以了解到:

对于由用户代理生成的条件请求导致的304未修改响应,用户代理必须表现得像服务器给出了一个具有适当内容的200 OK响应。

换句话说,浏览器总是会返回状态码200 OK,即使请求命中了浏览器缓存。

然而,规范也指出:

用户代理必须允许作者请求标头覆盖自动缓存验证(例如If-None-Match或If-Modified-Since),在这种情况下304未修改响应必须经过。

因此,有一种解决方法可以使304未修改响应对JavaScript代码可见。


2

当进行ajax请求时,您会得到响应代码。

if (request.readyState == 4) {
     if (request.status == 200) { // this number.
       ...

状态码200表示您正在获取数据的最新副本:

请求成功。响应返回的信息取决于请求中使用的方法 -

状态码304表示数据未更改,您将从浏览器缓存中获取它:

如果客户端执行了有条件的GET请求并允许访问,但文档未被修改,则服务器应该使用此状态代码进行响应。

了解更多状态码

更新:
您可以向URL添加缓存破坏器以确保始终命中服务器:

var ajaxUrl = "/path?cache="+(Math.random()*1000000);

4
听起来很合理,但与我看到的情况不一致。我似乎在响应中得到了200(在js和Chrome网络选项卡中进行验证),但网络选项卡告诉我响应来自缓存(由响应比网络选项卡说响应不是来自浏览器缓存时更快证实)。FYI这些是跨域请求-我加载一个来自origin1.com的页面,并向origin2.com发出ajax GET请求。 - rjkaplan
顺便说一句,我不知道这在XMLHTTPRequest中是如何工作的,但我知道使用某些HTTP头/值(根据https://developers.google.com/speed/docs/best-practices/caching看起来像是“过期”和“缓存控制:最大年龄”),对于某些资源可能*甚至不需要发出请求*,因此在这种情况下,状态代码并不一定有意义。 - JayC
很不幸,我在这种情况下无法找到XMLHttpRequest的行为可能是什么。也许其他人可以找到它 http://www.w3.org/TR/2012/WD-XMLHttpRequest-20121206/ - JayC
10
304仍表示正在向服务器发送请求。当内容被缓存以使浏览器无需进行网络IO时,您将始终收到200状态码。 - Sean Kinsey

1

这个答案基于您指的是仅浏览器缓存,没有发生304(modified-since、etag等)的情况。

检查请求花费了多长时间 - 如果它是从缓存中解析的,那么它应该接近0毫秒。


1

来自http://www.w3.org/TR/2012/WD-XMLHttpRequest-20121206/

对于由用户代理生成的条件请求导致的304未修改响应,用户代理必须表现得像服务器给出了一个带有适当内容的200 OK响应。用户代理必须允许作者请求头覆盖自动缓存验证(例如If-None-Match或If-Modified-Since),在这种情况下,304未修改响应必须通过。[HTTP]

我觉得这有点模糊。我的假设是,如果一个资源被有条件地请求,你会看到304响应代码。但是,正如我在另一条评论中解释的那样(来源:https://developers.google.com/speed/docs/best-practices/caching),如果该资源的最后一个响应服务器http头设置了Cache-Control: max-ageExpires在未来的某个时间点,甚至可能不会有请求。在这种情况下,我不确定应该发生什么。


0

你使用Firefox的Firebug吗?

Firebug有一个“Net”面板,其中包含一个“XHR”过滤视图。您应该能够通过请求阶段栏检查缓存信息,检查状态和/或单击三角形以检查“标头”。

已缓存还是未缓存

并非所有网络请求都是相等的-其中一些是从浏览器缓存而不是网络中加载的。 Firebug为每个请求提供状态代码,因此您可以快速扫描并查看您的站点如何有效地使用缓存来优化页面加载时间。

Firebug Net Panel文档在此处

Chrome / Safari / Opera都有类似的调试工具。刚刚在这里找到了一个好的列表(大多数应该都有工具来检查XHR)。


编辑:

为了在一定程度上挽回失误...

就像ibu已经回答的那样,我会首先检查响应的状态码。

如果你正在使用jQuery:

statusCode(added 1.5) Map Default: {} A map of numeric HTTP codes and functions to be called when the response has the corresponding code. For example, the following will alert when the response status is a 404:

$.ajax({
  statusCode: {
    404: function() {
      alert("page not found");
    }
  }
});

If the request is successful, the status code functions take the same parameters as the success callback; if it results in an error, they take the same parameters as the error callback.

jQuery 确实让生活变得轻松。 :)


1
我想OP是在谈论从JavaScript程序内部进行检查。 - I Hate Lazy
我刚刚更新了帖子,以澄清这一点。无论如何,感谢你的回答! - rjkaplan
我的错,我应该更仔细地看你的标签。这是我作为新手犯的错误。 ;) - mhulse

0

要从浏览器(如Google Chrome)检查,请按F12打开DevTools,导航到Network,刷新以获取一些数据,按XHR过滤,然后单击正确的XHR请求。 单击“headers”子选项卡,然后查看响应标头 ->缓存控制。

如果它说像no-cachemax-age=0这样的东西,则您没有缓存。

如果它说private,则您的浏览器正在缓存,但服务器不是。

如果它说public,则您正在同时缓存服务器端和客户端。

在Mozilla.org上获取更多信息

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接