浏览器端强缓存与协商缓存

强缓存

强缓存的实现

  • 浏览器请求一个资源文件,服务端在response header中对该文件做缓存配置,缓存时间、缓存类型都由服务端控制。
  • 之后每次用户正常打开这个页面,浏览器会判断缓存是否过期,没有过期就从缓存中读取数据并返回200状态。

cache-control

  1. max-age=31536000,表示资源最大有效时间的秒数,是一个相对值,不会因为用户修改本地时间而导致失效。
  2. public/private:public表示浏览器和代理服务器(nginx、CDN)都可以缓存;private表示仅浏览器端可以缓存。
  3. immutable:设置用户做了刷新操作(点击浏览器左上角的刷新按钮去刷新页面),也不向服务器发起http请求。
  4. no-cache:客户端缓存内容,但是是否使用缓存需要经过协商缓存来验证决定(即每次请求都会询问服务端)。
  5. no-store:浏览器端、服务器端都不缓存,即不使用强制缓存也不使用协商缓存。

协商缓存

  • 强制缓存内容失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
  • 协商缓存其实受强缓存的影响,强缓存过期了且Cache-Control不为no-store时是否缓存才由协商缓存决定。
  • 协商缓存是通过两对值来设置的: Last-Modified/If-Modified-Since 和 ETag/If-None-Match。

协商缓存的步骤

  • 请求资源时,把用户本地该资源的 etag 同时带到服务端,服务端和最新资源做对比。
  • 如果资源没更改,返回304,浏览器读取本地缓存。
  • 如果资源有更改,返回200,返回最新的资源。

ETag与Last-Modified

  • 浏览器第一次发送一个请求得到ETag/Last-Modified的值,在下一次请求request header中带上If-none-match/If-Modified-Since,根据浏览器端发送的值和服务器端的值进行比较,如果一致代表资源没有改变,服务器返回的正文为空的响应(304),让浏览器从缓存中读取资源,从而减少请求消耗。
  • Last-Modified 和 ETag同样可以同时配置,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

Last-Modified的缺点

  1. Last-Modified保存的是绝对时间,并且是精确到秒,所以如果资源在1秒内修改了多次的话,那就无法识别;
  2. 对于文件只改变了修改时间,内容不变,这时候也会使缓存失效,其实这个时候我们是不希望客户端重新请求的;
  3. 某些服务器不能精确的得到文件的最后修改时间

ETag的缺点

  • ETag的出现主要是解决了Last-Modified难以解决的问题,但是它也并非完美的,ETag每次服务端生成都需要进行读写操作(因为要生成hash),而Last-Modified只需要读取操作,ETag消耗更大一些。
上一篇:[转]Nginx 静态资源缓存设置


下一篇:深入理解浏览器的缓存机制