缓存机制

133 阅读6分钟

参考资料: 彻底理解浏览器的缓存机制

以下是我针对上篇文章的整理(压缩版),原文章写的比较详细。

1.HTTP请求

1.HTTP请求(request)报文:request line head body

请求行(method, path, version)-HTTP头(通用信息头、请求头、实体头)-请求报文主体(只有POST才有报文主体)

2.HTTP相应(response)报文:response line head body

状态行(version, status code, status text)-HTTP头(通用信息头、响应头、实体头)-响应报文主体

2.缓存过程

1.浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果和缓存标识

2.浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中

根据是否需要向服务器重新发起HTTP请求将缓存分为两个部分

  • 强制缓存:Cache-Control, Expires
  • 协商缓存:Etag/If-none-match, Last-modified/last-modified-since

1.强制缓存

总共有三种情况

  • 不存在该缓存结果和缓存标识,强制缓存失效,直接向服务端发起请求(跟第一次发起HTTP请求一致)。
  • 存在缓存结果和缓存标识,但该结果已失效,强制缓存失效,使用协商缓存。
  • 存在缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回结果。

规则:浏览器向服务器发起请求的时候,服务器将缓存规则放入HTTP响应报文的HTTP头中和请求结果一起返回给浏览器,控制强制缓存的字段是Cache-control(优先级高),Expires

①Expires

Expires是HTTP/1.0控制网页缓存的字段,其值为服务器返回该请求结果缓存的到期时间,即再次发起该请求时,如果客户端的时间小于Expires的值时,直接使用缓存结果。

到了HTTP/1.1,Expire已经被Cache-Control替代,原因在于Expires控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,那么如果客户端与服务端的时间因为某些原因(例如时区不同;客户端和服务端有一方的时间不准确)发生误差,那么强制缓存则会直接失效,这样的话强制缓存的存在则毫无意义。

②Cache-control

  • public:所有内容都会被缓存(客户端和代理服务器都可缓存)
  • private:所有内容只有客户端可以缓存,Cache-control的默认取值,数据只能存储到私有的cache,对某个用户专用,不能共享(response)
  • no-cache:客户端缓存内容,但是否使用缓存需要经过协商缓存来验证决定,不建议缓存到客户端,但是还是可以缓存的。
  • no-store:所有内容都不会缓存,即不使用强制缓存,也不使用协商缓存。
  • max-age=xxx(xxx is numeric):缓存内容在xxx秒后失效,缓存的时间,相对时间,从请求时间到过期时间的间隔,单位是秒。

③浏览器缓存存放位置

  • Cache-control(相对时间)的优先级比expires(绝对时间)高,同时存在取cache-control

  • 浏览器的缓存存放的位置:from memory cache/from disk cache

  • 访问一个网址、关闭、重新打开(form disk cache)、刷新(from memory cache)

  • from memory cache:内存缓存

    • 快速读取:内存缓存会编译解析后的文件,直接存入该进程的内存中,占据该进程一定的内存资源,方便下次运行使用的时候快速读取。
    • 时效性:一旦进程关闭,该进程的内存立即清空。
  • from disk cache:硬盘缓存

    • 直接把缓存写入硬盘中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢。
  • 在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。

  • 刷新页面

    image-20190826165423957

  • 具体可以看链接

2.协商缓存

  • 304,协商缓存生效

  • 200,协商缓存失效

①E-tag/If-none-match

Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)。

If-None-Match是客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。服务器收到该请求后,发现该请求头中含有If-None-Match,则会根据If-None-Match的字段值与该资源在服务器的Etag值做对比,一致则返回304,代表资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200。

②Last-modified/If-modified-since

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

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

③优先级别

Etag / If-None-Match优先级高于Last-Modified / If-Modified-Since,同时存在则只有Etag / If-None-Match生效。

3.总结

强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存,主要过程如下:

注意事项:

①在强制缓存生效的时候,是没有304概念的,因为并没有到服务器中读取缓存,仅仅是在from memory cache/from disk cache,并没有到服务器。

②缓存存放的位置,图片和Js文件都存入内存缓存,而css存入硬盘缓存中。