HTTP 协商缓存之ETag请求与响应流程

194 阅读2分钟

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>