HTTP缓存

本文链接https://www.cnblogs.com/echolun/p/9419517.html

为什么要有缓存(本地缓存)?

根据进来的请求,同时保存输出内容的副本,例:html页面,图片,文件(统称为副本),然后,当下一个请求来到的时候,如果是相同的URL,并且符合缓存规则,则直接使用副本响应访问请求,而不是向服务器再次发送请求。

使用缓存的好处

  1. 1.可以减小服务器的压力.
  2. 节省客户端流量,避免重复请求同样的内容.

使用缓存可能带来的问题

使用缓存之后,如果处理不好的话,可能造成客户端展示数据和服务器的最新数据冲突,造成客户端显示数据过久。

缓存相关的原理

浏览器第一次请求数据

在这里插入图片描述
第一次进行数据请求时,由于本地无缓存数据,没有各类关键字比对的过程,浏览器正常向Web服务器进行请求。

浏览器第二次请求数据

在这里插入图片描述
当浏览器再次请求时,这时候浏览器会根据请求头中的缓存的相关关键字来做出判断。

缓存相关的字段

阅读本文,先大概了解这些缓存字段是必须的,后面也会细说,先留个印象。

1.Cache-Control

请求/响应头,缓存控制字段,可以说是控制http缓存的最高指令,要不要缓存也是它说了算。

它有以下常用值

1.1 no-store:所有内容都不缓存

1.2 no-cache:缓存,但是浏览器使用缓存前,都会请求服务器判断缓存资源是否是最新,它是个比较高贵的存在,因为它只用不过期的缓存。

1.3 max-age=x(单位秒) 请求缓存后的X秒不再发起请求,属于http1.1属性,与下方Expires(http1.0属性)类似,但优先级要比Expires高。

1.4 s-maxage=x(单位秒) 代理服务器请求源站缓存后的X秒不再发起请求,只对CDN缓存有效(这个在后面会细说)

1.5 public 客户端和代理服务器(CDN)都可缓存

1.6 private 只有客户端可以缓存

2.Expires

响应头,代表资源过期时间,由服务器返回提供,GMT格式日期,是http1.0的属性,在与max-age(http1.1)共存的情况下,优先级要低。

3.Last-Modified

响应头,资源最新修改时间,由服务器告诉浏览器。

4.if-Modified-Since

请求头,资源最新修改时间,由浏览器告诉服务器(其实就是上次服务器给的Last-Modified,请求又还给服务器对比),和Last-Modified是一对,它两会进行对比。

5.Etag

响应头,资源标识,由服务器告诉浏览器。

6.if-None-Match

请求头,缓存资源标识,由浏览器告诉服务器(其实就是上次服务器给的Etag),和Etag是一对,它两会进行对比。

使用http缓存
1.让服务器与浏览器约定一个文件过期时间——Expires(GMT时间格式)。

日常请求对话

第一次请求

浏览器:服务器服务器,我现在需要一个a.js文件,帮我找找,然后给我。

服务器:次次找我要,烦不烦,文件给你可以,我们约定个时间(Expires),时间没到别来烦我了,返回了a.js以及过期时间Expires。

在这里插入图片描述
后续请求…

浏览器会先对比当前时间是否已经大于Expires,也就是判断文件是否超过了约定的过期时间。

时间没过,不发起请求,直接使用本地缓存。

时间过期,发起请求,继续上述的浏览器与服务器的谈话日常。

问题:假设Expires已过期,浏览器再次请求服务器,但a.js相比上次并未做任何改变,那这次请求我们是否通过某种方式加以避免?

2.让服务器与浏览器在约定文件过期时间的基础上,再加一个文件最新修改时间的对比——Last-Modified与if-Modified-Since

日常请求对话

第一次请求

浏览器:服务器服务器,我现在需要一个a.js,你找到了给我,顺便给我个过期时间,时间没到我保证不烦你!

服务器:瓜娃子,行,过期时间我给你,另外再给你一个文件最新修改时间Last-Modified,到时候文件过期了咱两核对文件修改时间,对得上你就别烦我,返回a.js+Expires+Last-Modified。

在这里插入图片描述
后续请求…

Expires未过期,浏览器机智的使用本地缓存,免得挨打。

Expires过期,服务器带上了文件最新修改时间if-Modified-Since(也就是上次请求服务器返回的Last-Modified),服务器将if-Modified-Since与Last-Modified做了个对比。

if-Modified-Since 与Last-Modified不相等,服务器查找了最新的a.js,同时再次返回Expires与全新的Last-Modified

if-Modified-Since 与Last-Modified相等,服务器返回了状态码304,文件没修改过,你还是用你的本地缓存。

如下图,请求头与响应头文件修改时间相同,所以返回了304,使用本地缓存:
在这里插入图片描述
问题:浏览器端可以随意修改Expires,Expires不稳定,Last-Modified只能精确到秒,假设文件是在1s内发生变动,Last-Modified无法感知到变化,这种情况下浏览器永远拿不到最新的文件(假想极端情况)。

3.让服务器与浏览器在过期时间Expires+Last-Modified的基础上,再增加一个文件内容唯一对比标记——Etag与If-None-Match。哦对了,我们说Expires不稳定,这里我们再加入一个max-age来加以代替(cache-control其中一个值)。

日常对话

第一次请求

浏览器:服务器服务器,你懂得~~~~~~

服务器:我不懂!a.js我给你,过期时间我也给你,再给你一个max-age=60(单位秒),Last-Modified你也给我收好,再加一个文件内容唯一标识符Etag。

后续请求…

60S内,不发起请求,直接使用本地缓存。(max-age=60代表请求成功缓存后的60S内不再发起请求,与Expires相似,同时存在max-age优先级要比Expires高,区别后面具体说)

60S后,浏览器带上了if-Modified-Since 与If-None-Match(上次服务器返回来的Etag)发起请求,服务器对比If-None-Match与Etag(不对比if-Modified-Since与Last-Modified了,Etag优先级比Last-Modified高,毕竟更精准)

If-None-Match与Etag不相等,说明a.js内容被修改过,服务器返回最新a.js与全新的Etag与max-age=60与Last-Modified与Expires

If-None-Match与Etag相等,说明a.js文件内容无任何改变,返回304,告诉浏览器继续使用之前的本地缓存。

如下图,服务器Etag与If-None-Match相同,所以返回了状态码304,由于优先级问题,虽然也有if-Modified-Since与Last-Modified,但这里不会对两者做对比。

在这里插入图片描述
问题:我们已经可以精确的对比服务器文件与本地缓存文件差异,但其实上面方案的演变都存在一个较大缺陷, max-age或Expires不过期,浏览器无法主动感知服务器文件变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值