写在前面
HTTP缓存技术是一种通过在客户端(例如浏览器)和服务器之间存储响应结果的机制来提高Web应用性能的技术。
对于一些具有重复的 HTTP 请求,我们可以把服务器响应的数据缓存在本地,那么下次就直接读取本地的数据,不必再通过网络来获取服务器的响应了,可以大大提高网页加载的速度。
HTTP缓存有两种实现方式,强缓存和协商缓存。
一、强缓存
当浏览器查询缓存时,可以不需要通过服务器,直接通过强制缓存查找是否存在本地缓存。
强缓存主要利用如下两个响应头部来实现,他们都表示浏览器在客户端的缓存有效期:
- Cache-Control:相对时间,优先级较高;
- Expires:绝对时间;
其具体流程如下:
在强制缓存的机制下,浏览器只需要在第一次请求资源时,将服务器返回的响应结果存储在本地缓存中,并在一定时间内直接从缓存中获取该资源,而不需要再次向服务器发送请求。
当浏览器再次请求该资源时,会先检查缓存是否过期。如果缓存未过期,则浏览器会直接从本地缓存中获取该资源,而不需要发送请求到服务器。如果缓存已过期,则浏览器会向服务器发送请求,并在响应中包含新的缓存标头,以更新缓存。
二、协商缓存
当我们调试网页的时候,可能会看到过某些请求的响应码是 304,这个就是告诉浏览器可以使用本地缓存的资源,通常这种通过服务端告知客户端是否可以使用缓存的方式被称为协商缓存。
实现协商缓存首先会检查强制缓存是否过期,然后再进行协商缓存。有两种方式,一种是通过时间,一种是通过唯一标识符(优先级更高)
(1)基于时间
该方式主要通过请求头部If-Modified-Since字段和响应头部Last-Modified字段来实现
Last-Modified:表示此响应资源的最后修改时间;If-Modified-Since:资源过期且响应头有Last-Modified,则再次发起请求时带上Last-Modified的时间,服务器收到请求发现If-Modified-Since字段,则进行比较:- 请求资源的最后修改时间 > Last-Modified :返回新资源,响应HTTP 200 OK
- 请求资源的最后修改时间 < Last-Modified :资源无修改,响应HTTP 304 走缓存
(2)基于唯一标识符
该方式主要通过请求头部的If-None-Match字段与响应头部中的ETag字段来实现
ETag:唯一标识响应资源If-None-Match:资源过期时,浏览器发现发现响应头有ETag,再次请求时将请求头If-None-Match设置为ETag的值,服务器收到请求对比- 资源有变化,响应HTTP 304 走缓存
- 资源无变化,响应HTTP 200 OK
基于唯一标识符的优势
ETag的优先级更高,主要由于以下几个方面
- Last-Modified修改,但其内容可能没有修改,会让客户端误以为资源修改重新发请求
- 有些服务器不能准确获取文件的最后修改时间