HTTP 协商缓存之ETag请求与响应流程
首次请求
客户端向服务器发送请求获取资源,首次请求报文中不包含与 ETag 相关的字段(如 If-None-Match)。示例如下:
GET /resource.html HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,\*/\*;q=0.8
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
首次响应
服务器接收到客户端的请求后,处理请求并返回资源。响应报文中包含 ETag 字段,用于标识该资源的当前版本。示例如下:
HTTP/1.1 200 OK
Date: Wed, 15 Nov 2023 12:00:00 GMT
Server: Apache/2.4.46 (Unix)
Content-Type: text/html; charset=UTF-8
Content-Length: 54321
Last-Modified: Tue, 14 Nov 2023 10:00:00 GMT
ETag: "abc123def456"
Connection: keep-alive
<!DOCTYPE html>
<html>
<head>
<title>Resource Page</title>
</head>
<body>
<p>这是资源的内容。</p>
</body>
</html>
后续请求
客户端在首次获取资源并缓存了 ETag 值后,再次请求相同资源时,会在请求报文中添加 If-None-Match 字段,并将之前缓存的 ETag 值作为其内容,发送给服务器以验证资源是否有更新。示例如下:
GET /resource.html HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,\*/\*;q=0.8
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
If-None-Match: "abc123def456"
后续响应
服务器接收到客户端的后续请求后,对比 If-None-Match 字段中的 ETag 值与当前资源的 ETag:
若匹配:表示资源未发生变化,服务器返回 304 Not Modified 状态码,不返回资源内容,让客户端使用缓存的资源。示例如下:
HTTP/1.1 304 Not Modified
Date: Wed, 15 Nov 2023 12:05:00 GMT
Connection: keep-alive
ETag: "abc123def456"
若不匹配:表示资源已更新,服务器返回 200 OK 状态码以及更新后的资源内容,同时可能更新 ETag 值。示例如下:
HTTP/1.1 200 OK
Date: Wed, 15 Nov 2023 12:05:00 GMT
Server: Apache/2.4.46 (Unix)
Content-Type: text/html; charset=UTF-8
Content-Length: 54322
Last-Modified: Wed, 15 Nov 2023 11:00:00 GMT
ETag: "abc789def012"
Connection: keep-alive
<!DOCTYPE html>
<html>
<head>
<title>Resource Page\</title>
</head>
<body>
<p>这是更新后的资源内容。\</p>
</body>
</html>