前端面试积累之http缓存

之前一直不太在意的点在面试和笔试中还是很重要的,花了一个小时功夫把它弄懂,可能还是有所欠缺,欢迎指点~~

浏览器缓存

定义 :把一个已经请求过的web资源拷贝一份副本存储在浏览器中。缓存会根据进来的请求保存输出的内容副本。当下一个请求来临的时候如果是相同的URL,缓存会根据缓存机制决定是直接使用副本响应还是请求原服务器再次发送请求。

浏览器缓存好处:

  1. 减少网络带宽消耗
  2. 降低服务器压力
  3. 减少网络延迟,加快页面打开速度

浏览器缓存规则

对于浏览器端的缓存来讲,这些规则是在HTTP协议头和HTML页面的Meta标签中定义的。他们分别从新鲜度和校验值两个维度来规定浏览器是否可以直接使用缓存中的副本,还是需要去源服务器获取更新的版本。

新鲜度(过期机制):也就是缓存副本有效期。一个缓存副本必须满足以下条件,浏览器会认为它是有效的,足够新的:

1. 含有完整的过期时间控制头信息(HTTP协议报头),并且仍在有效期内;

2. 浏览器已经使用过这个缓存副本,并且在一个会话中已经检查过新鲜度;

满足以上两个情况的一种,浏览器会直接从缓存中获取副本并渲染。

校验值(验证机制):服务器返回资源的时候有时在控制头信息带上这个资源的实体标签Etag(Entity Tag),它可以用来作为浏览器再次请求过程的校验标识。如过发现校验标识不匹配,说明资源已经被修改或过期,浏览器需求重新获取资源内容。

两种缓存机制

  1. 使用HTML Meta 标签

Web开发者可以在HTML页面的节点中加入标签,代码如下

<meta http-equiv="Pragma" content="no-cache">  
<!- Pragma是http1.0版本中给客户端设定缓存方式之一,具体作用会在后面详细介绍 -->

上述代码的作用是告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。

事实上这种禁用缓存的形式用处很有限:

a. 仅有IE才能识别这段meta标签含义,其它主流浏览器仅识别“Cache-Control: no-store”的meta标签。

b. 在IE中识别到该meta标签含义,并不一定会在请求字段加上Pragma,但的确会让当前页面每次都发新请求(仅限页面,页面上的资源则不受影响)。

2.使用缓存有关的HTTP消息报头,主要涉及的如下:
· Cache-Control与Expires

Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。

· Last-Modified/ETag与Cache-Control/Expires

配置Last-Modified/ETag的情况下,浏览器再次访问统一URI的资源,还是会发送请求到服务器询问文件是否已经修改,如果没有,服务器会只发送一个304回给浏览器,告诉浏览器直接从自己本地的缓存取数据;如果修改过那就整个数据重新发给浏览器;

Cache-Control/Expires则不同,如果检测到本地的缓存还是有效的时间范围内,浏览器直接使用本地副本,不会发送任何请求。两者一起使用时,Cache-Control/Expires的优先级要高于Last-Modified/ETag。即当本地副本根据Cache-Control/Expires发现还在有效期内时,则不会再次发送请求去服务器询问修改时间(Last-Modified)或实体标识(Etag)了。

一般情况下,使用Cache-Control/Expires会配合Last-Modified/ETag一起使用,因为即使服务器设置缓存时间, 当用户点击“刷新”按钮时,浏览器会忽略缓存继续向服务器发送请求,这时Last-Modified/ETag将能够很好利用304,从而减少响应开销。

· Last-Modified与ETag

你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的新鲜度
如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

浏览器HTTP请求流程:

这里有两张图比较好理解:
第一次请求:

第一次请求
这张图的大概意思就是对于第一次请求服务器端资源时不需要考虑缓存直接向web服务器发送请求,接收到服务器响应后直接由前端在页面上渲染出来。
再次请求:
注意这个时候浏览器缓存派上了用场,并且使用的是HTTP消息报头
再次请求
第二次甚至更多次的请求就会使用请求报头进行缓存判定,如果此时浏览器无缓存则和第一次请求一样,有缓存则使用Cache-Control与Expires判定缓存是否过期,没有过期就直接从缓存中取数据响应请求,过期则使用第二组请求报头中的ETag,由于它的优先级高于Last-Modified先进行判断,两个都经过了判断有更新就向服务器重新发起请求,若判断成功则跳转304从缓存中读取。最终渲染在前端界面上。

不能缓存的请求:

当然并不是所有请求都能被缓存,无法被浏览器缓存的请求如下:

1. HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache(HTTP1.0),或Cache-Control:max-age=0等告诉浏览器不用缓存的请求

2. 需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的

3. 经过HTTPS安全加密的请求(有人也经过测试发现,ie其实在头部加入Cache-Control:max-age信息,firefox在头部加入Cache-Control:Public之后,能够对HTTPS的资源进行缓存,参考《HTTPS的七个误解》)

4. POST请求无法被缓存

5. HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值