du blog
Hello, welcome to my blog
缓存
created: Mar 20 21updated: Mar 20 21

缓存是一种保存资源副本并在下次请求时直接使用该副本的技术,当web(浏览器)发现请求的资源已经被储存,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载,这样做的好处有:缓解服务器压力,提升性能(获取资源的时间更短了).

缓存相关的头有:

cache-control(HTTP/1.1定义)

请求头和响应头都支持这个属性,它通过不同的值 来定义不同的策略

no-store 没有缓存,每次客户端发起请求都会下载完整的响应内容

no-cache 缓存但需验证,每次发出请求时携带新鲜度验证字段,服务端会验证请求中的新鲜度字段,若未过期,返回304,则浏览器使用本地缓存副本

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

private 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)

max-age= 设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)

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

....等等(省略不常见的)

Expires(HTTP/1.0定义)

Expires 响应头包含日期,即在此之后响应过期

无效的日期,比如 0 代表该资源已经过期

如果在 cache-control 响应头设置 max-age 或者 s-maxage 那么Expires 会被忽略

这个字段的问题在于设置的为确定的日期,会存在时区问题

Last-modified/If-modified-Since

Last-modified 为响应头部字段,其中包含了源服务器认定资源修改的日期及时间,被用作一个验证器来判断收到的或者储存的资源是否一致,由于精度比Etag低,所以这是一个备用机制

If-modified-Since 浏览器在下次请求这个资源的时候,如果上次的响应头中存在 Last-modified 则将其添加到这次的请求头 If-modified-Since, 服务器判断未修改,则返回304,If-modified-Since只可以用在 GET 和 HEAD 请求中,当与 If-None-Match(Etag 对应的请求头) 一同出现时,它(If-Modified-Since)会被忽略掉,除非服务器不支持 If-None-Match

Etag/If-none-Match

Etag 为响应头部字段,标识资源的特定版本,

If-none-Match 浏览器下次请求这个资源的时候,如果上次的响应头中存在 Etag 则将其添加到这次的请求头 If-none-Match, 服务器判断资源为修改,则返回304

私有与共享缓存

私有缓存只能作用于用户,即被浏览器缓存,共享缓存可以被多个用户使用,即被代理服务器缓存

强缓存和新鲜度检测

强缓存(200 OK (from memory cache)/(from disk cache))

响应头中携带 Cache-control: max-age=;

浏览器在下次请求该资源的时候直接从缓存中读取,不会向服务器发送请求

(js/html会被存到内存中,css会被存到硬盘中)

新鲜度检测

当强缓存失效,浏览器携带上述的标识(If-modified-Since/If-none-Match),向服务器发送请求,服务器根据标识 判断资源是否修改,如果未修改则返回304,表示未过期,则浏览器从缓存中读取资源

这里需要注意的是,当在浏览器地址栏输入 url 请求的第一个资源是一定不会出现强缓存的

这里为示意图:

试探性过期

如果响应中没有cache-cotrol: max-age 首部(这里可以理解为没有cache-control首部),也没有expires首部,则浏览器可能会试探性的计算出一个最大使用期,作为强缓存时间