要让 fetch 不读旧数据,关键在于明确控制缓存行为:用 no-store 彻底禁用浏览器缓存,no-cache 触发服务端校验,reload 强制本次不读缓存;同时服务端必须配合返回正确的 cache-control 和 etag/last-modified 头。

要让 fetch 不读旧数据,关键不是“禁用缓存”,而是**明确控制缓存行为**,确保每次请求都拿到最新响应。浏览器默认的 cache: 'default' 会遵循 HTTP 缓存头(比如 Cache-Control: max-age=3600),这恰恰可能导致你读到过期缓存。真正避免旧数据,得按场景选对 cache 值,并配合服务端响应头协同生效。
明确要求跳过缓存:用 no-store
这是最直接、最可靠的方式——彻底不读缓存、也不存缓存,强制走网络。
- 适用场景:敏感操作(如提交表单、支付确认)、调试接口、数据必须 100% 实时(如交易行情、后台管理实时状态)
-
写法示例:
fetch('/api/user', { cache: 'no-store' }) -
注意:它不绕过服务端缓存,只禁用浏览器本地缓存;服务端仍需返回合适的
Cache-Control: no-store或private头,防止 CDN 或代理缓存旧数据
需要校验再用:用 no-cache
它允许复用本地缓存,但每次都向服务器发起条件请求(带 If-None-Match 或 If-Modified-Since),由服务端决定返回 304(用缓存)还是 200(给新数据)。
- 适用场景:数据更新不频繁但不能容忍明显过期(如用户资料、配置项),兼顾性能与新鲜度
-
前提:服务端必须正确返回
ETag或Last-Modified头,否则等效于default -
写法示例:
fetch('/api/config', { cache: 'no-cache' })
完全绕开浏览器缓存机制:用 reload
强制发起全新网络请求,忽略 memory cache 和 disk cache,但响应仍可能被后续请求缓存(取决于响应头)。
- 适用场景:手动刷新数据(如点击“重新加载列表”按钮),且你确定服务端响应头已设为不可缓存
-
区别于
no-store:reload只影响本次请求是否读缓存,不阻止响应被存入缓存;no-store是双向禁止 -
写法示例:
fetch('/api/orders', { cache: 'reload' })
服务端配合才是根本
前端 cache 参数只是“告诉浏览器怎么用缓存”,真正决定数据是否旧的,是服务端返回的缓存控制头:
- 对必须实时的接口,服务端应返回
Cache-Control: no-cache, no-store, must-revalidate - 避免只依赖前端设置,比如仅加
cache: 'no-cache'却服务端没返回ETag,结果还是读了过期缓存 - 调试时可用浏览器 DevTools 的 Network 面板查看 Request Headers(
Cache-Control)和 Response Headers,确认实际策略是否生效
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











