浏览器带来的 If-None-Match 怎么处理?ETag 怎么生成才合理?强弱 ETag 有什么区别?能不能用 ETag 防止两个人同时修改?这篇用 test client 逐个验证。
首次: 200 | ETag = "a9c15cbfcf470ec22cfefbd5f3e50aec62b048b8" | 正文 401 字节 | Content-Length 401 与 sha1(正文) 比较: True If-None-Match = "a9c15cbfcf4… → 304 | 正文 0 字节 | ETag = "a9c15cbfcf4… | Content-Length = None If-None-Match: "other" → 200 | 正文 401 字节 If-None-Match: * → 304 If-None-Match 带多个值(含正确的)→ 304 POST 带 If-None-Match → 405 (路由不允许 POST)
上一篇:send_file() 与 send_from_directory();下一篇:Last-Modified 与缓存响应。
响应的 ETag: W/"abc"
If-None-Match: 强 "abc" → 304
If-None-Match: 弱 W/"abc" → 304
If-None-Match: 不同 "xyz" → 200
werkzeug 的辅助:generate_etag(b"x") = 11f6ad8ec52a2984abaafd7c3b516503785c2072 | quote_etag("a", weak=True) = W/"a" | parse_etags('W/"a", "b"').to_header() = "b", W/"a"GET /manual → 200 "2526bca18f967ecc34148598c3828416" 带 ETag 再请求 → 304 (没有重新生成响应体)
第一个客户端 PUT If-Match = 它读到的 ETag → 200 updated
第二个客户端用同一个(已过期的)ETag PUT → 412 precondition failed
数据版本现在是: {'v': 2}200:正文 58890 字节 + 头约 150 字节;304:正文 0 字节 + 头约 87 字节;但服务器仍然生成并哈希了整个响应体(耗时见下) test client 耗时:200 465 µs;304 475 µs(服务器端的计算没有省:还是要生成响应体算 SHA-1)