浏览器的缓存机制

1.缓存过程

浏览器和服务器通信的方式为应答模式,即:浏览器发送HTTP请求 - 服务器响应该请求。浏览器第一次发送请求并收到响应后,会根据响应报文中HTTP头的缓存标识,决定是否缓存结果。如果是,则将请求结果和缓存标识存入浏览器缓存中。

  1. 浏览器每次发起请求,都会在浏览器缓存中查找该请求的结果和缓存标识;
  2. 浏览器每次拿到返回的结果,都会把该结果和缓存标识存入浏览器的缓存中。

根据浏览器是否需要向服务器发送HTTP请求,可以把缓存过程分为两个部分:强制缓存和协商缓存。

2.强制缓存

强制缓存就是浏览器在缓存中查找请求结果,并根据缓存标识决定是否使用缓存的过程。

实现强制缓存的字段分别是Expires和Cache-Control。

2.1 Expires

Expires指过期时间,其值为请求结果缓存的过期时间。具体来说,浏览器再次发送请求时,如果客户端的时间小于Expires的值时,直接使用缓存。由于Expires的值是服务端根据自己的时间设置的,当客户端和服务端时间有误差时,如客户端和服务端时区不同,强制缓存可能直接失效。

2.2 Cache-Control

Cache-Control是用来控制网页缓存的字段,有以下取值:

(1)public:所有内容都将被缓存,客户端和服务器都可缓存;

(2)private:默认值,所有内容只有客户端才能缓存;

(3)no-cache:客户端缓存内容,但是是否使用缓存需要经过协商缓存来验证决定;

(4)no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存;

(5)max-age=n:缓存内容将在n秒后失效。

当Cache-Control和Expires同时在响应报文头中存在时,只有Cache-Control生效。这是因为在无法确定客户端和服务端时间是否同步的情况下,Cache-Control相比于Expires是更好的选择。

3.协商缓存

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。

如果协商缓存成功,则返回状态码为304的空响应报文。如果协商缓存失败,则返回状态码为200的响应报文和更新后的资源。

实现协商缓存的字段分别为Last-Modified和ETag。

3.1 Last-Modified

Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间。

当客户端再次发送请求时,会在头部中携带If-Modified-Since字段,该字段的值是上次请求返回的Last-Modified值。服务器收到请求后,发现请求头含有If-Modified-Since字段,则会根据If-Modified-Since的字段值,与该资源在服务器最后的修改时间做对比,若服务器的资源最后被修改时间大于If-Modified-Since的字段值,则重新返回该资源,状态码为200;否则则返回304,表示资源无更新,可继续使用缓存文件。

3.2 ETag

ETag是服务器响应请求时,返回当前资源文件的一个唯一标识,一般通过hash算法生成。

当客户端再次发起请求时,会在请求头中携带If-None-Match字段,值为上次收到的ETag值。服务器收到请求后,会根据If-None-Match的字段值与该资源在服务器的ETag值做对比,如果一致则返回304,表示资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200.

当同时存在Last-Modified和ETag时,只有ETag才生效。

4.总结

强制缓存优先于协商缓存使用,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified/If-Modified和ETag/If-None-Match)。协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么服务器重新返回新的资源,浏览器将请求结果存入浏览器缓存中;生效则返回304,浏览器继续使用缓存。

上一篇:升级打怪-精读图解HTTP(第五章)


下一篇:浏览器缓存机制