Http缓存相关

115 阅读6分钟

缓存

缓存原理: 在首次请求后保存一份请求资源的响应副本,当用户再次发起相同的请求时,如果判断缓存命中则拦截请求,将之前存储的响应副本返回给用户,从而避免重新向服务器发起资源请求。

缓存技术种类: 代理缓存、浏览器缓存、网管缓存、负载均衡器。 大致可以分为:共享缓存私有缓存

共享缓存: 缓存内容可以被多个用户使用,如 公司内部架设的 web 代理,网关,负载均衡器

私有缓存: 只能单独被用户使用的缓存,如 浏览器缓存

Http 缓存

为了避免相同的资源被重复请求,例如 css、js 这些资源,如果没变化的情况下,不需要重复多次请求的,利用缓存即可提升网站性能与用户体验

Http 缓存又可以分为 强缓存协商缓存

强缓存: 无需判断缓存是否过期,直接使用

协商缓存: 浏览器会去询问服务器缓存的资源是否有更新,如果无更新那就返回 304,并让浏览器使用缓存,如果有更新则重新请求


强制缓存(强缓存)

如果浏览器判断所请求的目标资源有效命中,则可直接从强制缓存中返回请求响应无须与服务器进行任何通信

一般由 ExpiresCache-Control 两个字段控制, 其中 Cache-Control 优先级更高

响应头:

Expires : Thu, 24 Mar 2022 06:21:11 GMT
Cache-Control : max-age=1000

请求头:
Cache-Control : no-cache

Expires:

HTTP1.0 引入,用来表示一个固定的过期时间,客户端时间在这个时间内,即走强缓存,但是优先级比 Cache-Control

【缺陷】:
返回的到期时间是服务器端的时间,如果服务端和客户端时差有点大
且一旦过期需要重新去设置一个新的过期时间

Cache-Control:

HTTP1.1 引入了该字段,请求头,响应头都可以设置该字段。

请求头在无缓存(首次进入)的情况下为 no-cache , 之后如果该文件为 document 类型 则值为 max-age=0,其他例如xhr, jpeg 类型无该字段

【上述内容为本人测试所得,具体细节不是很清楚,只是发现了这个现象,document 类型 一般为进入的那个根目录,比如 localhost:8080/


Cache-Control 缓存配置的其他参数

no-cache 和 no-store

【响应头设置】 no-cache ,表示为进行协商缓存, 直接与服务器协商验证缓存有效性,若缓存未过期,则使用本地缓存。设置 no-store ,表示禁止使用任何缓存策略,这 2 个值为互斥属性,不能同时设置

【请求头设置】 no-cache ,此时不管服务器那边设置的是什么,都不会走缓存


private 和 public

也是一组互斥属性,用以明确响应资源是否可被代理服务器进行缓存,默认为 private

若设置为 public ,表示该响应资源既可以被浏览器缓存,又可以被代理服务器缓存

若设置为 private ,表示该响应资源只可以被浏览器缓存


max-age 和 s-maxage

【响应头设置】 max-age ,表示客户端的响应资源的过期时长,单位为秒

【请求头设置】 max-age ,当服务端想走强缓存时,该值会让其去 协商缓存

s-maxage 为代理服务器缓存的代理时间

【注】当后端配置了强缓存,同时又配置了协商缓存,例如 max-age=10 , 则 10s 内会采用强缓存,10s 过后,如果没有协商缓存,那么重新请求一次,紧接着继续 10s 强缓。

如果有协商缓存,那么会先走协商缓存的判断,文件没变化,那么返回 304 状态码,并且继续 10s 强缓存,如此反复。


协商缓存

在使用本地缓存之前,需要向服务器发起一次 GET 请求与之协商当前浏览器保存的本地缓存是否已过期

常用的两种: last-modified(最后修改时间) 和 ETag(实体标签)

根据 last-modified

【响应头】设置 last-modified : xxxUTCTimeCache-Control : no-cache 后的第二次请求,会在请求头上生成 If-Modified-Since 字段,后端根据该字段,去判断该文件是否修改了没修改就返回 304 给前端

last-modified: 文件的最后修改时间(位于响应头)

If-Modified-Since: 给后端校验用的(位于请求头)

【缺陷】:

如果文件内容没有变化,单纯只是改了些属性,那么修改时间也会变化,但这时候就重新请求一次,很明显不太合适

文件内容变得太快,1s变好几次,last-modified的最小单位是秒

根据 ETag

为了弥补 last-modified 的不足,从 HTTP1.1 规范新增了 ETag 的头字段

主要是服务器为不同资源进行 hash 运算生成 Etag 字符串,只要文件内容存在差异,那么 ETag 标签就会不同

etag: 实体标签(位于响应头)

If-None-Match: 给后端校验用的(位于请求头)

【缺陷】:

生成文件资源的 ETag ,需要额外开销,如果 文件资源大,多那么对服务器是会有些压力

另一方面,ETag 字段生成分为 强验证 和 弱验证,
强验证根据资源内容进行生成,保证每个字节都相同,但速度慢,
弱验证则是根据部分属性进行生成,速度快,但无法确保每个字节都相同

一:HTTP/1.0 和 HTTP/1.1 区别?

  1. 缓存处理 ==> 1.1 增加了缓存控制策略和缓存头
  2. 带宽优化以及网络连接的使用 ==> 1.0 会将你需要的某一部分所在的整个包都发送给你,1.1 只会将那一个部分给你
  3. 错误通知管理 ==> 1.1 增加了 24 个错误状态码
  4. Host 头处理
  5. 长连接 ==> 1.1 支持(比如 浏览器实时聊天)

二:HTTP/1.x 和 HTTP/2.0 区别?

  1. 新的二进制格式
  2. 多路复用 ==> 2.0 同一个连接并发处理多个请求,同一个连接可以并行发送多个请求给服务器,服务器也并行返回多个请求
  3. header 数据压缩 ==> 使用 HPAC 算法,对 header 进行压缩,这样传输速度更快了
  4. 服务器推送 ==> 服务器会把客户端需要的资源一起推送给客户端 例如:客户端向服务器请求 CSS,然后服务器发现该 CSS 需要 JS 一起运行,所以服务器会带上 JS 一起推送给客户端,而不需要客户端再次请求

三: HTTP 和 HTTPS 区别?

HTTP ==> HTTP -> TCP HTTPS ==> HTTP -> SSL/TLS -> TCP HTTPS 多了加密解密步骤

  1. HTTPS 需要 CA 请求证书 (付费的)
  2. HTTP 都是明文传送,HTTPS 是通过 SSL 加密的
  3. 连接方式,端口完全不同,HTTP 是 80 端口,HTTPS 是 443 端口
  4. HTTPS 防止运营商劫持

总结:

1.0 老版本 ------- 不支持长连接 1.1 主流版本 ------- 支持长连接,但同时发送的资源数量过小(4-6 个) 2.0 最新版 ------ 同时发送资源的数量提升(8-12 个)