200表示服务器返回完整资源,含响应体;304表示服务器仅确认缓存有效、不返回资源体,浏览器直接使用本地缓存。区别在于200是真实传输数据,304是协商验证后复用缓存。

200 和 304 都表示请求“成功”,但背后的行为和资源交付方式完全不同。关键区别不在结果,而在是否真正从服务器取了新数据。
200:真返回,带完整响应体
服务器确实处理了请求,并把完整的资源(HTML、JS、图片等)发给了浏览器。这是首次访问或缓存失效后的标准响应。
- 响应中包含 HTTP 头 + 实际内容(body),比如一个 120KB 的 CSS 文件会完整传输
- 浏览器收到后,会把内容存入内存或磁盘缓存,供后续复用
- 在 Nginx 日志里看到 200,说明这次请求走完了完整流程:接收 → 查找文件 → 读取 → 发送
304:假返回,不发内容,只确认“没变”
浏览器先带着缓存的 If-Modified-Since 或 If-None-Match 请求头去问服务器:“我手上的这个版本还有效吗?”服务器检查后发现资源没更新,就只回一个极简响应——状态码 304,不带 body。
- 响应体为空,只含少量头信息(如
Date、ETag),通常不到 200 字节 - 浏览器收到 304 后,直接从本地缓存里取出之前存好的内容来用
- 日志中记为 304,说明服务器省了读文件、序列化、网络发送的开销,对高并发场景很友好
怎么判断该走 200 还是 304?
取决于两个条件是否同时满足:
- 客户端请求里带了有效的缓存验证头(如
If-Modified-Since) - 服务端资源自上次响应后确实未修改(时间戳或 ETag 匹配)
只要任一条件不成立,Nginx 就会返回 200 并重新发送资源。
日志中常见但容易误解的情况
同一个 JS 文件,第一次访问是 "GET /app.js HTTP/1.1" 200;刷新后变成 "GET /app.js HTTP/1.1" 304——这不代表出错,而是缓存机制在正常工作。如果始终只看到 200,可能是因为没配缓存头(Expires 或 Cache-Control),或者浏览器强制刷新(Ctrl+F5)绕过了协商缓存。











