304 not modified 是缓存协商成功状态,表示资源未修改,浏览器应复用本地缓存;需通过 status 判断而非回调,服务端须返回 etag/last-modified 且前端主动复用缓存数据。

304 Not Modified 是服务器返回的缓存协商成功状态,表示资源未修改,浏览器应使用本地缓存版本。Ajax 请求中它不会触发 success 回调(如 jQuery 的 done()),也不会进入 error,而是走“成功路径”但响应体为空——关键在于正确识别和利用它。
检查响应状态码与响应头
Ajax 请求完成后,必须主动读取 XMLHttpRequest.status 和 responseHeaders 判断是否为 304:
- 原生
fetch中,response.status === 304为真,但response.body为空,且response.ok为false(因为 304 不属于 2xx 范围) - jQuery 的
$.ajax默认将 304 视为“成功”,但jqXHR.status仍是 304,jqXHR.responseText为空字符串,需手动判断 - 注意:
ETag或Last-Modified等缓存校验头由浏览器自动携带,无需 JS 手动设置,但服务端必须返回对应头才能触发 304
复用本地缓存数据(而非重新请求)
304 意味着数据没变,理想做法是跳过解析、直接使用上次缓存的结果:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 在发起 Ajax 前,把上一次响应数据(如 JSON 解析结果)存在内存或
Map中,键可用 URL + 参数生成 - 收到 304 后,不调用
JSON.parse,直接返回缓存数据,避免解析失败或空值问题 - 若用
localStorage持久化缓存,需同步更新过期时间或校验字段,防止缓存 stale
确保服务端正确支持协商缓存
前端无法单方面触发 304,依赖服务端配合:
- 首次响应必须包含
ETag(如ETag: "abc123")或Last-Modified - 后续请求带
If-None-Match(对应 ETag)或If-Modified-Since,服务端比对后决定返回 200 还是 304 - Node.js/Express 示例:用
res.set('ETag', crypto.createHash('md5').update(data).digest('hex'))生成 ETag,并用req.fresh判断是否返回 304
避免常见误操作
很多开发者因忽略 304 特性导致逻辑异常:
- 不要依赖
response.text()或response.json()处理 304 响应——它们会 resolve 空内容,可能引发JSON.parse("")报错 - 不要在
catch中处理 304——它不是网络错误,fetch不会 reject - 禁用缓存(如加时间戳参数)会绕过 304,失去性能优势,调试时可临时关闭,但线上应保留协商机制
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










