知易通
第二套高阶模板 · 更大气的阅读体验

Ajax请求被缓存怎么办?常见场景与解决方案

发布时间:2025-12-09 05:25:17 阅读:171 次

最近在开发一个后台管理系统时,遇到个让人头疼的问题:页面刷新后,某些数据还是老的。查了半天才发现,是浏览器把Ajax请求给缓存了。明明接口返回的是新数据,前端却拿不到,问题就出在缓存上。

为什么Ajax请求会被缓存?

很多人以为Ajax默认不缓存,其实不然。GET请求在某些浏览器下(比如IE、部分版本的Chrome)会默认被缓存,尤其是当URL完全相同时。比如你发了个请求:/api/user?id=123,下次再发同样的URL,浏览器可能直接从缓存取结果,根本不会走网络。

这种情况在开发阶段可能不明显,但一旦上线,在用户端就容易出问题,尤其是数据更新频繁的场景,比如订单状态、用户积分、实时消息等。

怎么判断是不是缓存导致的?

打开浏览器开发者工具,看Network面板。如果某个请求的状态码显示的是 304 Not Modified 或者 Size 栏显示 (from memory cache)(from disk cache),那基本可以确定是缓存生效了。

解决方法一:URL加时间戳或随机参数

最简单粗暴的方法,就是在请求URL后面加一个不重复的参数,比如时间戳:

$.ajax({
  url: "/api/user?id=123&_t=" + new Date().getTime(),
  type: "GET",
  success: function(data) {
    console.log(data);
  }
});

这样每次请求的URL都不一样,浏览器就不会用缓存。也可以用随机数:

url: "/api/user?id=123&_r=" + Math.random()

虽然看起来有点土,但在老项目里特别管用,尤其是一些第三方库封装的请求没法改配置的时候。

解决方法二:设置请求头禁止缓存

如果你用的是原生fetch或者能控制请求头,可以在发送时加上禁用缓存的指令:

fetch("/api/user?id=123", {
  method: "GET",
  headers: {
    "Cache-Control": "no-cache",
    "Pragma": "no-cache"
  }
})

注意,这只能建议浏览器不要缓存,不能百分百保证。服务器端的缓存策略优先级更高。

解决方法三:服务端设置缓存控制

更彻底的办法是在服务器响应头里明确告诉浏览器别缓存。比如后端返回时加上:

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

这样无论前端怎么发,浏览器都会重新请求。适合对数据一致性要求高的接口,比如支付结果查询、用户权限变更等。

jQuery用户注意:设置cache: false

如果你还在用jQuery的$.ajax,可以直接设置cache: false

$.ajax({
  url: "/api/user",
  type: "GET",
  cache: false, // 自动加时间戳
  success: function(data) {
    console.log(data);
  }
});

jQuery内部会自动在URL后面加_={timestamp},省得你自己拼。

实际场景举例

有个客户反馈说修改了头像,刷新页面还是旧的。排查发现是因为头像地址是/api/avatar?user_id=888,而这个接口被CDN缓存了5分钟。后来我们在生成URL时加了头像更新时间戳:/api/avatar?user_id=888&v=1678901234,问题就解决了。

有时候不是技术不够,而是细节没考虑到。缓存本是为了提升性能,但用错了地方反而成了坑。