如何判断 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 看起来像Expires
和Cache-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-age
或 Expires
在未来某个时间设置,则可能甚至没有请求。在这种情况下,我不确定应该发生什么。
【讨论】:
【参考方案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-cache
和max-age=0
之类的内容,那么您没有缓存。
如果显示private
,那么您的浏览器正在缓存,但服务器没有。
如果它显示public
,那么您正在缓存服务器端和客户端。
More info at Mozilla.org
【讨论】:
以上是关于如何判断 XMLHTTPRequest 是不是命中浏览器缓存的主要内容,如果未能解决你的问题,请参考以下文章
如何验证 Cloud CDN 响应是不是是缓存命中(或来自 CDN)
OpenGL:如何通过 API 知道顶点是不是正在命中帧缓冲区