接口每次响应都带 ETag,第二次请求也带上了 If-None-Match,服务端还是回 200 和完整 JSON。抓包看响应体 84KB,一次都没有变成 304。碰到这种情况,我一般先确认改动有没有真的生效。
原因不复杂,ETag 的值在每次响应时重新算,用响应时间或者随机数拼出来的串,两次请求算出的值不一样,协商自然对不上。中间那层代理还可能把 ETag 改写成 W/ 开头的弱校验值,客户端原样回传,服务端做的却是强比较。
「ETag 协商」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。
curl -sI https://api.example.com/v1/orders/42 curl -sI -H 'If-None-Match: "a1b2c3"' https://api.example.com/v1/orders/42
具体做法是,把两次响应的 ETag 原样打印出来对比 不一致就去看生成逻辑;ETag 只对响应体做摘要 别把时间戳和请求 ID 这类每次变的值拼进去;确认代理没有改写 ETag 关掉它的 etag 模块再测一次;服务端比较时同时接受强校验和弱校验两种格式 按业务决定要不要忽略 W/ 前缀。
最后用这个标准收尾,连续两次请求第二次返回 304 响应体为空 代理那一层也不再出现 200。
