从输入URL到页面加载的过程(6) - 单独拎出来的缓存问题,http缓存

Posted by cody1991 on July 25, 2020

from 从输入 URL 到页面加载的过程?如何由一道题完善自己的前端知识体系!

作为进阶回头再来看看:从输入 URL 到页面加载完成的过程中都发生了什么事情?

单独拎出来的缓存问题,http 缓存

缓存可以分为 强缓存 和 协商缓存

  • 强缓存时 200 from cache,浏览器判断本地是否过期,未过期直接使用,不发 http 请求
  • 协商缓存 304 会发起请求,服务器来告诉浏览器是否过期,未过期使用本地文件

使用 ctrl+F5 可以让协商缓存无效,但是对于强缓存,未过期的话需要更新路径才能发起新的请求

缓存头部介绍

常用的缓存头部

If-None-Match/E-tag

If-Modified-Since/Last-Modified

Cache-Control/Max-Age、Pragma/Expires

强缓存的是

(http1.1)Cache-Control/Max-Age (Max-Age 是值,不是头部) (http1.0)Pragma/Expires

协商缓存是

(http1.1)If-None-Match/E-tag (http1.0)If-Modified-Since/Last-Modified

html 头部也是可以控制的

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

但是支持不好,代理服务器也不会支持

头部的区别

http1.0 中的缓存控制:

  • Pragma:严格来说,它不属于专门的缓存控制头部,但是它设置 no-cache 时可以让本地强缓存失效(属于编译控制,来实现特定的指令,主要是因为兼容 http1.0,所以以前又被大量应用)
  • Expires:服务端配置的,属于强缓存,用来控制在规定的时间之前,浏览器不会发出请求,而是直接使用本地缓存,注意,Expires 一般对应服务器端时间,如 Expires:Fri, 30 Oct 1998 14:19:41
  • If-Modified-Since/Last-Modified:这两个是成对出现的,属于协商缓存的内容,其中浏览器的头部是 If-Modified-Since,而服务端的是 Last-Modified,它的作用是,在发起请求时,如果 If-Modified-SinceLast-Modified 匹配,那么代表服务器资源并未改变,因此服务端不会返回资源实体,而是只返回头部,通知浏览器可以使用本地缓存。Last-Modified,顾名思义,指的是文件最后的修改时间,而且只能精确到 1s 以内

http1.1 中的缓存控制:

  • Cache-Control:缓存控制头部,有 no-cache、max-age 等多种取值
  • Max-Age:服务端配置的,用来控制强缓存,在规定的时间之内,浏览器无需发出请求,直接使用本地缓存,注意,Max-AgeCache-Control 头部的值,不是独立的头部,譬如 Cache-Control: max-age=3600,而且它值得是绝对时间,由浏览器自己计算
  • If-None-Match/E-tag:这两个是成对出现的,属于协商缓存的内容,其中浏览器的头部是 If-None-Match,而服务端的是 E-tag,同样,发出请求后,如果 If-None-MatchE-tag 匹配,则代表内容未变,通知浏览器使用本地缓存,和 Last-Modified 不同,E-tag 更精确,它是类似于指纹一样的东西,基于 FileEtag INode Mtime Size 生成,也就是说,只要文件变,指纹就会变,而且没有 1s 精确度的限制。

Max-Age 相比 Expires

Expires 使用的是服务器端的时间,但是有时候会有这样一种情况 - 客户端时间和服务端不同步

可能就会出问题了,造成了浏览器本地的缓存无用或者一直无法过期

所以一般 http1.1 后不推荐使用 Expires

Max-Age 使用的是客户端本地时间的计算,因此不会有这个问题,因此推荐使用 Max-Age

注意,如果同时启用了 Cache-ControlExpiresCache-Control 优先级高。

E-tag 相比 Last-Modified

Last-Modified:表明服务端的文件最后何时改变的,它有一个缺陷就是只能精确到 1s,然后还有一个问题就是有的服务端的文件会周期性的改变,导致缓存失效

E-tag:是一种指纹机制,代表文件相关指纹,只有文件变才会变,也只要文件变就会变,也没有精确时间的限制,只要文件一遍,立马 E-tag 就不一样了

如果同时带有 E-tagLast-Modified,服务端会优先检查 E-tag