304 Not Modified通常表示缓存验证成功,不是页面抓取失败。客户端带着已有版本的验证器请求资源,服务器确认未修改后返回304,不再传正文;客户端继续使用缓存版本。需要警惕的是内容已更新,服务器却错误地说“没变”,让用户或爬虫继续沿用旧页面。验证304是否正确,必须同时测试未修改和已修改两种情况。
先分清缓存命中与条件请求
浏览器直接使用仍新鲜的缓存,可能根本不向服务器请求。条件请求则是已经发生了网络访问,客户端通常带If-None-Match或If-Modified-Since,让服务器判断缓存是否还能复用。开发者工具里显示“来自缓存”和网络返回304,含义不同。
MDN的304说明指出,304用于条件GET或HEAD请求,响应不应包含正文,并应带上对应200响应所需的相关缓存头。因此,抓取日志中304的响应体大小为零并不奇怪,也不能仅凭零字节认定页面被清空。
Google在抓取问题排查文档中说明,支持If-Modified-Since和If-None-Match,并可在304时复用上次抓取版本;但并非每一次抓取都会发送这些头。不要把“支持条件请求”解释成Google每次必定按同一模式访问。

本地教学服务器实际请求截图:状态与响应体长度来自执行记录,仅验证样例的缓存逻辑,不代表生产站表现。
用旧ETag做一组可复查的测试
选一条自己有权检查的公开URL,先发送不带条件头的GET,保存正文、ETag、Last-Modified与Cache-Control。再把实际取得的ETag完整放入If-None-Match,注意引号和可能存在的弱验证前缀,不要凭空编一个值当作服务器当前标签。
curl -sS -D first.txt -o first.html \
'https://example.com/products/part/'
curl -sS -H 'If-None-Match: "实际取得的标签"' \
-D check.txt -o check.html \
'https://example.com/products/part/'
对于带有效If-None-Match的GET,若请求选中的表示与旧ETag匹配,遵循HTTP条件请求规范的源站应返回304,不能仅以“缓存策略不同”解释相同条件下的200。收到200时,先检查条件头是否到达判断层、是否选中了不同表示,以及当前ETag是否已变化。没有304本身不证明收录故障,但条件请求实现仍应单独核对。
第二阶段应在测试环境或经授权的发布流程中修改一段可识别的正文,再带旧ETag请求同一URL。若这时仍得到304,而在相同表示与请求条件下,产品资料的语义确实已经改变,就应查验证器生成逻辑。不要为了测试擅自修改生产产品资料,也不要只改变无关文件后期待页面ETag必然变化。
哪些实现会把新内容误判成旧内容
一种常见设计缺陷是只按模板文件更新时间生成Last-Modified,产品数据变了却不更新验证器。另一种是多台应用节点输出不同正文,却共享一个固定ETag。还有些缓存中间层复用了旧验证器,导致源站、边缘和浏览器各自以为拿到的是同一版本。
ETag不是必须使用某种哈希算法。MDN的HTTP缓存文档说明,服务器可用内容哈希或版本号等方式生成它。工程上需要保证验证器准确对应实际选中的表示;多语言、压缩方式或其他会影响响应的变体,也要按真实缓存策略处理。
If-None-Match和If-Modified-Since同时出现时,ETag条件优先。排查不要先看到日期没变就宣布Last-Modified是根因,应把请求头完整保存。若服务器没有ETag,可单独测试修改时间逻辑,但分布式时钟、秒级精度及内容生成方式都需要纳入判断。
索引指令更新也不能留在旧版本里
页面取消noindex或修改canonical后,要确认公开访问能读到新的相关指令。正确的304可以更新相应响应元数据,但错误的版本判断不能用“节省带宽”来解释。涉及HTML指令变化时,保留新旧正文样本与验证器,检查条件请求是否让旧HTML持续复用。
如果无条件请求本身拿到的就是旧正文,问题尚未到304判断这一步,应先看CDN旧缓存与源站对照。临时添加参数拿到新版,只说明另一个请求路径或缓存键有新内容,不能替代正式URL的验证。
弱ETag也要按原值检查
按MDN对ETag的说明,ETag可能带W/前缀,表示弱验证器。它关注语义上的等价,不应被测试脚本自动删掉前缀或引号后再发送。对缓存验证而言,先保留服务器实际提供的值;如果团队改变验证器生成方式,需要确认现有客户端与中间缓存如何处理,而非只检查标签看起来是否更短。
正文压缩、模板插入动态时间或不同地区返回差异内容时,也可能让每次响应的字节不完全相同。测试前应确认当前响应表示及缓存键,别把所有字节变化都归结为业务资料更新。相反,若产品参数明显改变却沿用完全不变的固定验证器,就应有明确的实现依据,否则容易形成旧内容复用。
在测试记录里保留原始响应头和正文文件,再另做便于阅读的对照。原始文件能帮助开发发现重复ETag、代理重写或头字段丢失;仅抄出一个状态码,会把这些线索丢掉。测试请求应保持低频,避免为了验证缓存反而制造无意义回源。
交付结论应写出两组实际结果
合格的记录包含首次版本、当前版本、条件头、状态、正文是否存在,以及返回的验证器。写成“未修改时复用正确,修改后旧验证器取得新版”更清楚;“304已优化”没有说明验证了什么。本地样例可以帮助理解,但生产配置仍需要按实际链路测试。
光算的谷歌SEO服务可按项目讨论网站技术建议与缓存排查。正确的条件请求有助于避免无谓传输,不是排名信号的承诺;当内容能稳定更新、抓取可用后,再用真实日志与Search Console观察Google的处理情况,不因304数量上升就宣布SEO效果提升。