ajax 不会自动处理304响应,需前端检查status并结合本地缓存应对:首次请求获取etag,后续由浏览器自动发条件请求;304时response为空,应通过getcacheddata()读取自维护缓存。

JavaScript 中的 Ajax 本身不会自动处理 304 Not Modified 响应——它会正常触发 success(或 then)回调,但响应体为空,且 responseText、response 等字段为 null 或空字符串。浏览器已将缓存内容用于本次请求,但 JS 层无法直接读取该缓存结果。关键在于:**你不需要手动“获取”304缓存的内容,而是要让浏览器在发起请求时就决定是否复用缓存,并确保你的代码能安全应对空响应。**
确保后端正确返回 304 并设置缓存头
这是前提。后端必须:
- 对支持缓存的资源(如 JSON API),根据
If-None-Match(ETag)或If-Modified-Since请求头判断资源未变更 - 返回
304 Not Modified状态码,且不带响应体 - 响应中包含有效的缓存控制头,例如:
Cache-Control: public, max-age=3600ETag: "abc123"Last-Modified: Wed, 01 Jan 2025 00:00:00 GMT
前端 Ajax 请求需启用条件请求头
浏览器只有收到带 ETag 或 Last-Modified 的历史响应后,下一次同 URL 请求才会自动带上 If-None-Match 或 If-Modified-Since。因此:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 首次请求必须由浏览器发出(比如页面加载时 fetch),并成功收到含
ETag的 200 响应,后续请求才能触发 304 - 避免在 JS 中手动覆盖
Cache-Control或禁用缓存(如加时间戳参数、设置cache: 'no-store') - 使用
fetch时,默认行为就是遵循 HTTP 缓存规则;若用XMLHttpRequest,确保没设置xhr.setRequestHeader('Cache-Control', 'no-cache')
在 JS 中安全处理 304 响应
你无法从 304 响应中读取数据,但可以利用浏览器已注入的缓存行为,并在代码中兼容空响应:
-
不要依赖 response body 判断数据有效性:304 响应的
response.text()或response.json()会 resolve 为空或抛错,应先检查response.status - 推荐写法(fetch):
fetch('/api/data')
.then(res => {
if (res.status === 304) {
// 浏览器已从缓存加载,此时可尝试从本地缓存(如内存变量、localStorage)读取上一次的数据
// 或直接跳过更新 UI(如果状态未变)
console.log('Using cached response');
return getCachedData(); // 你自己维护的缓存副本
}
return res.json();
})
.then(data => {
updateUI(data);
cacheData(data); // 同时更新本地缓存,供下次 304 时使用
});
- 注意:
getCachedData()和cacheData()需你自行实现(例如用 Map 存储最近响应,或结合 localStorage)。浏览器缓存不可被 JS 直接读取,只能靠你同步维护一份
更健壮的做法:用 Service Worker 拦截并注入缓存
如果你需要完全可控地复用缓存内容(包括在 304 时返回之前缓存的完整响应),可借助 Service Worker:
- 在
fetch事件中检查event.request.cache和响应状态 - 当收到 304,可主动从
caches.match()中取出之前缓存的完整 Response 并返回 - 这样 JS 层拿到的就是一个正常的 200 响应,无需特殊处理 304
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










