304是服务器对条件请求(If-Modified-Since或If-None-Match)的响应,表示资源未修改,客户端应使用本地缓存;它由服务端根据Last-Modified或ETag头校验后返回,HTML文件本身无法主动触发。

304 是服务端响应,不是 HTML 能“创建”的
HTML 文件本身不能主动触发或生成 304 Not Modified。这个状态码完全由服务器在收到带条件请求头(如 If-Modified-Since 或 If-None-Match)的 HTTP 请求后,校验资源未变时返回。浏览器是否发这类请求,取决于上一次响应中是否包含 Last-Modified 或 ETag,以及 Cache-Control 是否已过期。
常见误解是给 HTML 加个 meta 标签就能控制 304 —— 但 在现代浏览器中**基本无效**,HTTP 缓存策略只认响应头,不认 HTML 内的 meta。
让 HTML 走 304 的必要条件:服务端必须返回正确的响应头
要让后续请求有机会拿到 304,首次响应必须携带至少一组协商缓存标识:
-
Last-Modified:基于文件系统修改时间,Nginx 默认开启,Apache 需配置FileETag MTime Size -
ETag:内容哈希值,更精确;Nginx 开启需显式写etag on;,且建议配合expires或Cache-Control -
Cache-Control: max-age=...:决定强缓存有效期;过期后浏览器才会发条件请求
例如一个有效的首次响应头应类似:
HTTP/1.1 200 OK Cache-Control: max-age=1800 Last-Modified: Thu, 22 May 2026 15:10:33 GMT ETag: "a1b2c3d4"
为什么你改了 HTML 却还收到 304?
这是最常被误判的问题。现象:本地改完 HTML 文件,刷新页面却仍是 304,内容没更新。原因通常是:
- 静态服务器(如 Nginx)读取的是磁盘文件的
mtime,而某些编辑器(如 VS Code 保存时可能先删后写),导致Last-Modified时间戳未更新 - CDN 或反向代理缓存了旧的
ETag或响应头,没随源站同步刷新 - 开发时用了
Cache-Control: no-cache,它强制每次走协商,但服务端又没及时更新ETag,结果一直返回304
验证方式:用 curl -I http://yoursite.com/index.html 查看响应头中的 Last-Modified 和 ETag 是否与你预期的修改时间/内容一致。
前端能做的只有“配合”,别试图绕过协议
前端无法强制服务器返回 304,但可以避免破坏协商链路:
- 不要在 fetch / axios 中手动删掉
If-None-Match或If-Modified-Since—— 浏览器自动加的,删了反而变 200 - 调试时别长期开着 DevTools 的 “Disable cache”,它会让浏览器跳过所有缓存逻辑,包括 304
- SPA 路由下 HTML 通常只加载一次,后续是 JS 控制视图;真正需要 304 的是
.js、.css、.png等静态资源
真正难调的永远是服务端那层:ETag 计算逻辑是否稳定、Last-Modified 是否被构建工具重写、CDN 是否透传了原始头信息——这些才是 304 失效的根因。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











