HTTP:浏览器缓存机制

http缓存策略由缓存存储策略,缓存过期策略,缓存对比策略三部分构成,这三部分并不是完全分开设置的,具体设置方法和缓存执行结果如下:

缓存存储策略

缓存存储策略用于判断是否缓存 http响应内容。

请求头/响应头

Cache-Control

  • public(可缓存到代理服务器和客户端),
  • private(可缓存到客户端),
  • max-age(可缓存到客户端,超过指定时间后过期,单位秒),
  • s-maxage(可缓存到代理服务器,超过指定时间后过期,单位秒),
  • no-cache(可缓存到客户端,缓存后立即过期,每次访问都需从服务器验证资源有效性200或304,相当于max-age=0, must-revalidation),
  • no-store(不进行任何缓存)。

Cache-Control: private,max-age=3600。

缓存过期策略

缓存过期策略用于判断是否直接读取本地缓存(否则向服务器发送请求,但不一定重新下载)。

请求头/响应头

Expires

配置规则为一个绝对时间点(如:Fri, 02 Nov 2018 10:30:57 GMT)。

在缓存存储策略中设置max-age事实上也起到了设置缓存过期策略的作用,当设置cache-control : max-age=3600时,相当于expires : 当前时间+3600秒。

需要注意的是超过过期时间并不一定会从服务器下载新的文件,最终结果还要根据三种策略综合判定。

Cache-Control

  • max-stale(缓存资源过期后的指定时间内仍然视为有效,相当于将过期时间设置为 Expires : Expires+max-stale),
  • min-fresh(缓存资源过期前的指定时间内即视为无效,相当于将过期时间设置为 Expires : Expires-min-fresh)。

当多项配置同时存在时,客户端会按照最保守的策略执行(即最先过期的规则)。

缓存对比策略

缓存对比策略用于验证缓存资源的有效性(从而判断继续使用缓存资源还是从服务器重新下载)。

响应头

ETag (服务器资源唯一标识符,如:7b7d124715407066726535778e)。

HTTP/1.1 引入了Etag(Entity Tags)主要为了解决 Last-Modified 无法解决的一些问题。如某些文件可能会周期性更新,但内容并不改变(仅改变修改时间),这时候我们并不希望客户端认为这个文件被修改了而重新 下载;某些文件修改非常频繁,例如:在一秒的时间内进行多次修改,If-Modified-Since 能检查到的粒度是 s 级的,无法判断(或者说 UNIX 记录 MTIME 只能精确到秒);某些服务器不能精确的得到文件的最后修改时间等等。

nginx中Etag是根据资源更新时间转换为16进制,结合内容长度生成,如下:

Content-Length: 612
Last-Modified: Tue, 23 Apr 2019 10:18:21 GMT
ETag: "5cbee66d-264"

express 中采用 etag 库生成Etag标签,静态资源一般都只是生成的长度-时间戳,动态接口可以配置hash等。

koa 的 etag 插件底层还是 express 的 etag库。

Last-Modified ,值为请求资源上一次更新时间,如:Fri, 02 Nov 2018 10:30:57 GMT

请求头

If-None-Match  值为上一次收到的(多个)ETag,如果与当前ETag不同,则重新下载资源,否则返回304。

If-Match  值为上一次收到的(多个)ETag,仅在与当前ETag相同时进行请求,一般用于更新资源。

If-Modified-Since ,值为上一次请求的响应头中的Last-modified ,如果与当前Last-modified不同,则重新下载资源,否则返回304。

If-Unmodified-Since,值为上一次请求的响应头中的Last-modified ,仅在与当前ETag相同时返回响应。

使用Etag比对的优先级和精确性均高于使用Last-modified比对,同时存在时前者将覆盖后者。

强制缓存

通常只要客户端存在缓存资源,且Cache-Control配置max-age,min-fresh,max-stale和Expires配置中的最保守策略尚未过期,即触发强制缓存,浏览器直接使用缓存资源,响应状态码为200(form memory cache)或200(from disk cache)。如:

Cache-Control:max-age=1days,min-fresh=1days,max-stale=1days

Expires:当前时间三天后

根据上面的配置可以计算出以下缓存过期策略:

Expires策略  三天后

max-age策略  当前时间 + 1天 = 一天后

max-stale策略 三天后(即Expires配置)+ 1天 = 四天后

min-fresh策略 三天后(即Expires配置)- 1天 = 两天后 

综上,最保守策略为一天后,此时如果浏览器中存在缓存资源,则会直接读取。

协商缓存

如果客户端存在缓存资源,缓存存储策略和缓存过期策略综合计算得出的最保守策略已经过期,即触发协商缓存。

  1. 此时浏览器会优先使用ETag比对:
    1. 自动设置请求头中的If-None-Match为上一次请求该资源的ETag值,如果相同则响应返回304,浏览器继续使用缓存资源,否则重新从服务器中下载资源。
    2. 在验证资源有效或重新下载资源之后浏览器会自动更新缓存资源的Cache-Control,Expires,Date(缓存资源更新时间),Age(该缓存资源已经存在时间)。
  2. 如果没有ETag配置则使用Last-Modified比对,浏览器在请求头中会设置If-Modified-Since为上次请求的Last-Modified值,其余执行原理与Etag比对类似。
  3. 如果响应头中没有指定过期策略,则浏览器会将该资源响应结果中的Date和Last-Modified的时间差的10%(单位秒)加上当前时间作为Expires时间。

禁止静态资源缓存

对于需要禁用缓存的场景可以用以下几种方法实现:

  1. 请求头设置Cache-Control:no-cache,no-store,must-revalidation
  2. 设置静态资源版本号,如:<script src="./js/index.js?version=1.0.1"></script>(这种方法对于静态资源比较灵活可控,但是对代理服务器不起作用)
  3. 设置meta标签<meta http-equiv="Cache-Control" content="no-cache,no-store,must-revalidation">(对代理服务器不起作用)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值