http缓存详解(强缓存、协商缓存相关字段以及缓存流程解析)

缓存相关字段:

http1.0:pragma、expires

http1.1:cache-control、last-modified、if-modified-since、etag、if-none-match

强缓存:

不发起http请求,直接使用本地缓存,比如浏览器地址栏回车,使用浏览器的刷新按钮,在Expires或max-age生效的情况下,触发强缓存。

不经常被修改的文件,通常用强缓存

协商缓存(弱缓存):

在使用本地缓存前,先与服务器协商,核对缓存文件是否为最新。请求头携带If-None-Match或If-Modified-Since,也可都携带。

一、Cache-control请求头/响应头

1.客户端设置

max-age:表示本地缓存的资源将在xx秒之后过期

no-cache:跳过强缓存和协商缓存阶段,直接请求服务器

no-store:不在本地缓存数据。

2.服务端设置

max-age:让客户端在xx秒内,不发起请求,直接使用本地缓存。(max-age=0相当于no-cache)

s-maxage: 覆盖max-age或者Expires头,但是仅适用于共享缓存(比如各个代理),私有缓存会忽略它。

no-cache:强制浏览器重新发送请求,但浏览器会缓存到本地。(不使用缓存)

no-store: 强制浏览器重新发送请求,并且禁止浏览器缓存数据。(不缓存)

public: 响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存

private: 响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。私有缓存可以缓存响应内容,比如:对应用户的本地浏览器。

must-revalidate:一旦资源过期(比如已经超过max-age),在成功向原始服务器验证之前,缓存不能用该资源响应后续请求。

immutable:响应正文不会随时间而改变。资源未过期,客户端不应发送重新验证请求头(例如If-None-Match或If-Modified-Since)来检查更新,即使用户显式地刷新页面。

二、Pragma 请求头/响应头

pragma:no-cache

http1.0使用的缓存字段,现在不常用,向后兼容只支持 HTTP/1.0 协议的缓存服务器,与 Cache-Control: no-cache 效果一致。

三、过期时间expires和cache-control:max-age

Expires: Thu, 29 Oct 2020 11:29:05 GMT 和 cache-control:max-age=10效果类似,max-age是相对时间,表示过了10s过后 再重新请求 而expires是绝对时间,表示过了这个时间,再重新请求。

1.首次请求

客户端:请求a.js文件

服务器:返回a.js + cache-control:max-age=10 + 过期时间Expires(Expires: Thu, 29 Oct 2020 11:29:05 GMT)

注意:expires主要是用来兼容http1.0版本的浏览器

如果在Cache-Control响应头设置了 "max-age" 或者 "s-max-age" 指令,那么 Expires 头会被忽略。

2.后续请求

客户端:

(1)先判断本地时间是否超过了过期时间,若时间没过,不发起请求,直接使用本地缓存。

(2)时间过期,重复步骤1

问题:

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

四、Last-Modified(响应头)和if-Modified-Since(请求头)

同时设置cache-control:max-age last-modified表示强制缓存和协商缓存共用,若cache-control设置为max-age=0或者no-cache,则只有协商缓存生效

1.首次请求

客户端:请求a.js文件

服务器:返回a.js + cache-control:max-age=10 + last-modified(Thu, 22 Oct 2020 10:23:29 GMT) + 状态码200

2.后续请求

客户端:

(1)先判断本地时间是否超过了过期时间max-age,若未过期,使用浏览器缓存。

(2)过期,客户端带上if-Modified-Since(也就是上次请求服务器返回的Last-Modified),服务器将客户端传来的if-Modified-Since与自己的Last-Modified做对比。

(3)若if-Modified-Since ≠ Last-Modified,服务器返回新的a.js + 新的Last-Modified + cache-control:max-age=10

(4)若if-Modified-Since = Last-Modified,服务器返回状态码304,表示文件没修改过,让客户端使用浏览器的缓存。

问题:

1. 资源文件每次一被修改,Last-Modified也会跟着修改,如果修改过后又进行版本回退,内容跟浏览器已缓存的一致,但用户还是要重新请求资源,因为Last-Modified改变了。

2. Last-Modified只能精确到秒,如果恰好在一秒之内变化了,Last-Modified是不会修改成功的。

五、Etag(响应头)和if-None-Match(请求头)

服务端生成资源文件的唯一标识符Etag,资源更改,则一定要生成新的Etag

对于大文件,不会根据整个文件去生成hash 可以使用文件大小或者文件开头去生成hash

md5是 摘要算法,也叫hash算法

1. 是单向的 无法反解

2. 对于相同内容 加密结果相同;不同的内容 加密结果的长度相同

1.首次请求

客户端:请求a.js文件

服务器:返回a.js + cache-control:max-age=10 + last-modified(Thu, 22 Oct 2020 10:23:29 GMT) + Etag + 200

2.后续请求

客户端:

(1)先判断本地时间是否超过了过期时间max-age,未过期,则使用浏览器缓存。

(2)若过期,客户端带上if-Modified-Since + if-None-Match,服务器先将客户端传来的if-None-Match与自己的Etag做对比。

(3)若if-None-Match ≠ Etag 服务器返回新的a.js + 新的Etag + Last-Modified + cache-control:max-age=10

(4)若if-None-Match = Etag,服务器返回状态码304,表示文件没修改过,让客户端使用浏览器的缓存,if-Modified-Since和Last-Modified 也不需要再比较了。

面试点睛:

1. 为什么有了Last-Modified还要用etag?

  • 防止Last-Modified变了,但文件内容没变的情况下,浏览器需要重新请求服务器
  • 防止文件在1s内发生变化,而Last-Modified不变

2. 用户行为如何触发缓存?

  • 打开网页,地址栏输入地址: 查找 disk cache 中是否有匹配。如有则使用;如没有则发送网络请求。
  • 普通刷新 (F5):因为 TAB 并没有关闭,因此 memory cache 是可用的,会被优先使用(如果匹配的话)。其次才是 disk cache
  • 强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。

推荐阅读:

CSS 超出隐藏实现限制字数的功能代码(多浏览器支持)

JS函数集合大全

Javascript中最常用的61段经典代码

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

短暂又灿烂的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值