HTTP缓存的实现原理是:客户端(浏览器)和服务器通过Cache-Control、Expires等报文头部以及Last-Modified/ETag等机制来控制缓存的行为。
客户端第一次请求资源时,会将响应报文根据Cache-Control/Expires头部缓存一定时间。在缓存期内,后续请求会直接从缓存中获取资源,不会向服务器发起请求。
但是在某些情况下,客户端需要向服务器确认缓存的资源是否变化,这时会使用Last-Modified/ETag头部。
- Last-Modified:服务器在响应中发送资源的最后修改时间,客户端会在后续请求中带上If-Modified-Since头部发送此时间。如果资源未修改,服务器返回304状态码;修改了,返回200与新的资源。
- ETag:服务器在响应中发送资源的唯一标识(如Hash值),客户端会在后续请求中带上If-None-Match头部发送此ETag。如果资源未修改,服务器返回304;修改了,返回200与新的ETag。
由此可见,使用Last-Modified/ETag可以避免不必要的重复下载资源,从而优化网络带宽和客户端性能。
代码示例:
缓存响应:
HTTP/1.1 200 OK
Content-Type: text/html
Cache-Control: max-age=60 // 缓存60秒
ETag: "10c1-4183e1ea83b84"
<h1>Content</h1>
If-Modified-Since:
GET /resource HTTP/1.1
If-Modified-Since: Wed, 09 Jun 2021 10:18:14 GMT
HTTP/1.1 304 Not Modified // 资源未修改,直接返回304
If-None-Match:
GET /resource HTTP/1.1
If-None-Match: "10c1-4183e1ea83b84"
HTTP/1.1 304 Not Modified