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

Posted

技术标签:

【中文标题】如何判断 XMLHTTPRequest 是不是命中浏览器缓存【英文标题】:How to tell if an XMLHTTPRequest hit the browser cache如何判断 XMLHTTPRequest 是否命中浏览器缓存 【发布时间】:2012-11-26 19:59:22 【问题描述】:

如果可以判断(在 javascript 执行中)GET XMLHTTPRequest 是否命中浏览器缓存而不是从服务器获取响应?

【问题讨论】:

【参考方案1】:

你使用火狐的Firebug吗?

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

Cached or not cached

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

萤火虫Net Panel docs are here.

Chrome/Safari/Opera 都有类似的调试工具。刚找到一个good list here(大多数应该有检查XHR的工具)。


编辑:

为了有点救赎自己……

作为ibu has answered,我也会先检查响应的状态码。

如果您使用的是 jQuery:

statusCode(added 1.5) 地图默认值: 数字 HTTP 代码和函数的映射,当 响应有相应的代码。例如,以下将 响应状态为 404 时发出警报:

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

如果请求成功,状态码函数取相同 参数作为成功回调;如果导致错误,他们 采用与错误回调相同的参数。

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

【讨论】:

我想 OP 正在谈论从 JavaScript 程序中进行检查。 我刚刚更新了帖子以说明这一点。无论如何,谢谢你的回答! 我的错,我应该更仔细地查看您的标签。代表我的菜鸟错误。 ;)【参考方案2】:

此答案基于您的意思是仅浏览器缓存的假设,没有发生 304(修改后,etag 等)。

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

【讨论】:

【参考方案3】:

发出ajax请求时,你会得到响应码

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

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

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

status 304 表示数据没有改变,您将从浏览器缓存中获取它:

如果客户端执行了条件 GET 请求并且允许访问,但文档没有被修改,服务器应该用这个状态码响应。

Read more on Status Code

更新: 您可以在您的 URL 中添加缓存破坏器,以确保您始终访问服务器:

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

【讨论】:

听起来很合理,但与我所看到的不一致。我似乎在响应中得到了 200 秒(如在 js 和 Chrome 网络选项卡中验证的那样),但网络选项卡告诉我响应来自缓存(证实响应比网络选项卡显示的要快得多响应不是来自浏览器缓存)。仅供参考,这些是跨域请求 - 我为 origin1.com 加载页面并向 origin2.com 发出 ajax GET 请求。 顺便说一句,我不知道这如何与XMLHTTPRequest 一起工作,但我知道对于某些http 标头/值(根据developers.google.com/speed/docs/best-practices/caching 看起来像ExpiresCache-Control: max-age)那里甚至可能不是针对某些资源的请求,因此在这种情况下,状态代码不一定有意义。 不幸的是,在这种情况下,我很难找到 XMLHttpRequest 的行为。也许其他人可以找到它w3.org/TR/2012/WD-XMLHttpRequest-20121206 304 仍然意味着它正在访问服务器。当内容被缓存以便浏览器永远不需要做网络 IO 时,你总是得到 200。【参考方案4】:

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

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

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

【讨论】:

【参考方案5】:

来自XMLHttpRequest spec:

对于用户代理导致的 304 Not Modified 响应 生成的条件请求用户代理必须像服务器一样操作 用适当的内容给出了 200 OK 响应。

换句话说,浏览器将始终给出状态码 200 OK,即使对于命中浏览器缓存的请求也是如此。

但是,规范中还说:

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

因此,有一种解决方法可以使 304 Not Modified 响应对您的 JavaScript 代码可见。

【讨论】:

【参考方案6】:

要通过 Google Chrome 等浏览器进行检查,请按 F12 打开 DevTools,导航到网络,刷新以获取一些数据,按 XHR 过滤,然后单击正确的 XHR 请求。单击“headers”子选项卡,然后查看 Response Headers -> cache-control。

如果它显示no-cachemax-age=0 之类的内容,那么您没有缓存。

如果显示private,那么您的浏览器正在缓存,但服务器没有。

如果它显示public,那么您正在缓存服务器端和客户端。

More info at Mozilla.org

【讨论】:

以上是关于如何判断 XMLHTTPRequest 是不是命中浏览器缓存的主要内容,如果未能解决你的问题,请参考以下文章

如何验证 Cloud CDN 响应是不是是缓存命中(或来自 CDN)

OpenGL:如何通过 API 知道顶点是不是正在命中帧缓冲区

java中如何判断发送的请求是不是得到响应

如何让 Axios 使用 Fetch 而不是 XMLHttpRequest

c#怎样动态判断wpf窗口某一区域是不是有控件存在

AJAX学习笔记