什么是 HTTP 缓存
缓存是一种保存资源副本并在下次请求时直接使用该副本的技术
缓存的基础是建立在两者文件路径完全相同的情况下
http缓存主要针如css,js,图片等更新频率不大的静态文件
缓存技术的优点
- 减少重复数据请求,避免通过网络再次加载资源,节省流量
- 降低服务器压力,提升网站性能
- 加快客户端加载网页的速度,提升用户体验
缓存类型
强缓存
不需要发送请求到服务端,直接读取浏览器本地缓存
由响应头中的
Cache-Control或者Expires字段控制,表示资源的缓存有效时间
-
Expires是 http 1.0 的规范,值是一个GMT格式的时间点字符串(expires: Thu, 17 Mar 2022 07:19:55 GMT)。这个时间点代表资源失效时间,如果之后的请求时间戳在这个时间戳之前,则命中强缓存。如果服务器时间和客户端时间偏差较大时,会导致缓存混乱。 -
Cache-Control是 http1.1 的规范,使用max-age来设置资源可以被缓存多长时间,值是一个相对时间,相对于用户请求时间,单位为秒。用户请求时间 +max-age即为强缓存有效时间,在有效时间内重复请求,会命中强缓存。Cache-Control可设置的其他值:no-cache: 浏览器缓存了数据,但是再次请求时,是不直接使用强缓存,强制使用协商缓存,即每次请求都必须向服务器发送no-store: 直接禁止浏览器缓存数据,每次请求资源都会向服务器获取完整的资源public: 可以被所有用户缓存,包括终端用户和cdn等中间件代理服务器private: 只能被终端用户的浏览器缓存s-maxage: 和max-age一样,不过它只针对代理服务器而言
-
强缓存优先级
max-age 比 Expires 优先级高,并存时,采用 max-age 值
协商缓存(对比缓存)
最终由服务器决定是否使用缓存,即客户端获取资源时,会向服务器发送请求,用服务器判断是否使用缓存数据。
协商缓存下如果命中缓存,服务器端响应的状态码为304(not modified)。
两组规则:
Last-Modified / If-Modified-Since和ETag / If-None-Match
-
Last-Modified / If-Modified-Since1、服务器响应浏览器的响应时,会在响应头里添加一个字段
Last-Modified,值为资源的最后修改时间
2、浏览器之后再请求时,会在请求头添加字段
If-Modified-Since, 值为服务器上一次响应的Last-Modified值
3、服务器会对比源资源最后修改时间和web请求头里的
If-Modified-Since字段值。如果大于If-Modified-Since,这说明资源有更新,缓存已失效,浏览器则不能再使用之前的缓存副本,返回完整的资源数据并响应码为200;如果相等,则表明资源未失效,响应头信息中状态码为304,响应消息体中没有数据
-
ETag / If-None-Match1、服务器响应浏览器的响应时,会在响应头里添加一个字段
ETag,值为资源的一个唯一标识(生成规则实现方式不一,由具体的服务器决定)
2、浏览器之后再请求时,会在请求头添加
If-None-Match,值为服务器上一次响应的ETag值
3、服务器比对源资源的
ETag是否和 web 请求头的If-None-Match字段值一致。不一致则说明文件有更新,本地缓存已失效,响应完整的资源数据并响应码为200;如果一致,则命中协商缓存,响应码为304
- 协商缓存两组规则的优先级
当
Last-Modified / If-Modified-Since和ETag / If-None-Match并存时,使用ETag / If-None-Match
HTTP 缓存的流程图

Q & A
1、既然已经存在 Last-Modified / If-Modified-Since,为什么规范里由引入了 ETag / If-None-Match ?
ETag值都是由服务器为每一个资源生成的唯一标识串,只要资源有变化就这个值就会改变。
HTTP1.1 用 ETag 来判断请求的文件是否被修改,主要为了解决 Last-Modified 无法解决的一些问题:
1、一些文件也许会做周期性的更改,但是他的内容并不更改(仅仅改变的修改时间),这个时候并不希望客户端认为这个文件被修改了重新GET
2、某些文件修改非常频繁,1秒内修改了N次,If-Modified-Since 能检查到的粒度是秒级的,这种判断无法修改
3、某些服务器不能精确的得到文件的最后修改时间
为此,HTTP1.1 引入了 ETag 。但标准并没有规定ETag的内容是什么或者说要怎么实现,唯一规定的是`ETag 需要放在双引号内。
max-age 和 Expires 的区别
1、max-age 是 http 1.1 的属性, Expires 是 http 1.0 的属性,为了做到向下兼容,一般写两个。但在 http 1.1 的环境下, max-age 比 Expires 优先级高
2、max-age 是相对过期时间, Expires 是绝对过期时间。 max-age 在浏览器成功缓存文件后,只需相对成功之后的多长时间不再发起请求就好了,而 Expires 总是需要服务器返回一个精准的 GMT 格式的日期,并以这个日期为标准来判断缓存是否过期。本地时间和服务器时间有较大偏差时,缓存就会不准确
单页面缓存应用实践
-
html文件:应用唯一入口,也是加载资源的唯一入口,所以建议html文件禁止使用缓存Cache-Control: no-store,保证用户请求到的html文件永远为最新的 -
JS、CSS文件:项目基本使用webpack等构建工具,资源名称由 HASH值 进行标识,资源更新时,则 HASH值 会发生改变,文件路径改变,故不再满足缓存条件,首次加载时必然请求服务器。所以缓存策略可以将max-age配置一个绝对大的值 -
image、media等媒体资源:根据网站实际情况做缓存策略
provisional headers are shown (显示临时报头)

上图表示:真正的请求并没有被发送,出现此种情况的原因是真正的Header只有在服务器端响应的时候更新。显示临时报文的几种情况:
1、命中强缓存,请求未发出
2、跨域,请求被浏览器拦截
3、请求被浏览器插件拦截
4、服务器出错或者超时,服务器端没有响应























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)