HTTP 的缓存机制有哪些?

146 阅读3分钟

你可以介绍一下HTTP 的缓存机制吗?

好的,面试官

首先,我大概介绍一下 HTTP 缓存的背景吧,

HTTP 发展到 1.1 版本,在请求传输过程中也存在携带了很多冗余且重复的数据, 比如相同的首部,比如请求头多个固定字段没压缩等等,导致请求性能的下降; 所以这时候提高 HTTP1.1 性能的一种方法就是减少请求,所以缓存机制也就提了上来了。

HTTP 的缓存机制

HTTP 的缓存机制分为两种:一种是强制缓存、一种是协商缓存,强制缓存不成功才走协商缓存。

强制缓存

强制缓存是浏览器的主动行为,在发请求之前它会先看看是否有缓存,缓存是否过期;如果没过期,则直接使用缓存; 这时候,返回的 code 是 200 ,但是会有 from disk cache 的标识,标志着该请求走的是强制缓存。

强制缓存的实现主要依靠 Respond Head 中的两个字段: Cache-Control:相对时间 或 Expires:绝对时间 一般来说, Cache-Control 可以设置得更精细些,所以推荐使用 Cache-Control 来实现强制缓存; 如果上述两个字段同时存在的话, Cache-Control 的优先级更高。

综上,强制缓存就是和拿请求的时间和 Cache-Control (或者 Expires)中的时间作比较, 只要没过期,则浏览器直接返回缓存的数据。

协商缓存

协商缓存是指服务器告诉浏览器是否使用本地缓存,其实本质上就是交由服务器来判断本地缓存是否过期; 若没过期,则直接返回 304 ,告诉浏览器使用本地缓存。 走到了协商缓存,说明强制缓存已经失效,HTTP 请求已经发出

协商缓存的实现也有两种:

  1. 请求头部中的 If-Modified-Since 字段与响应头部中的 Last-Modified 字段实现 Last-Modified 记录着资源的最后修改时间,  If-Modified-Since表示从某个时间段开始到现在资源未发生改变 在请求的时候,发现有 Last-Modified 字段,则会将该时间填进 If-Modified-Since 向服务器发出请求; 服务器根据浏览器发来的时间和目标资源的 Last-Modified 比较,如果Last-Modified 的时间比较小, 说明资源未发生改变,直接响应 304,让浏览器使用本地缓存; 否则返回最新的资源数据,响应 200.

  2. 请求头部中的 If-None-Match 字段与响应头部中的 ETag 字段 响应头部中 Etag:唯一标识响应资源;(思想上有点像 Hash, MD5) 在请求的时候,发现有 Etag字段,则会将该值填进 If-None-Match 向服务器发出请求; 服务器根据浏览器发来的值和目标资源的 Etag 比较,如果两个值相等, 说明资源未发生改变,直接响应 304,让浏览器使用本地缓存; 否则返回最新的资源数据,响应 200.

综上,强制缓存是由浏览器自己决定资源是否过期,协商缓存是交由服务端来判断; 无论是 最后的修改时间 还是 资源的唯一标识 ,目的就是用于判断资源是否过期; 相对来说 资源的唯一标识 这种实现方式更为可靠, 最后的修改时间 的实现方式存在时间篡改等不可靠性