很多人在写前端代码时都会用到 fetch 发起网络请求,但可能没太注意它到底会不会走缓存。其实这个问题挺常见的,尤其是在做页面优化或者调试接口的时候。
fetch 默认会走浏览器缓存
fetch 请求和传统的 XMLHttpRequest 一样,遵循浏览器的 HTTP 缓存机制。也就是说,如果你之前请求过某个接口,而服务器返回了缓存头(比如 Cache-Control 或 Expires),那么下一次用 fetch 请求同一个地址时,浏览器可能会直接从缓存中读取结果,而不是真的再发一次请求。
举个例子:你在做一个天气应用,每隔几分钟调一次接口获取最新数据。但如果服务器设置的是缓存 5 分钟,那你在这 5 分钟内连续调用 fetch,很可能拿到的都是缓存里的旧数据。
如何避免使用缓存
如果你希望每次请求都获取最新数据,可以手动设置 cache 模式。fetch 提供了一个 cache 选项,其中 no-cache 和 no-store 都能控制缓存行为。
fetch('/api/weather', {\n method: 'GET',\n cache: 'no-cache' // 强制重新验证,不使用本地缓存\n})\n.then(response => response.json())\n.then(data => console.log(data));
这里的 no-cache 并不是完全不用缓存,而是每次都会向服务器发起请求确认资源是否更新;而 no-store 才是彻底禁止缓存,连请求都不走本地。
也可以通过加参数绕过缓存
一个更简单粗暴的办法是在 URL 后面加个时间戳或随机数,让每次请求的地址看起来都不一样:
fetch(`/api/weather?t=${Date.now()}`)\n.then(response => response.json())\n.then(data => console.log(data));
这招虽然有点“土”,但在调试阶段特别实用,尤其是当你不确定后端缓存策略的时候。
服务器也能决定是否允许缓存
最终能不能缓存,还得看响应头怎么说。比如服务器返回了 Cache-Control: no-store,那浏览器就不会缓存这个响应,fetch 自然也不会用到。反过来,如果给了一个很长的 max-age,那即使你没做任何处理,fetch 也会优先使用缓存。
所以开发时最好和后端沟通清楚缓存策略,别自己瞎猜。