缓存是一种保存资源副本并在下次请求时直接使用该副本的技术,当web(浏览器)发现请求的资源已经被储存,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载,这样做的好处有:缓解服务器压力,提升性能(获取资源的时间更短了).
缓存相关的头有:
cache-control(HTTP/1.1定义)
请求头和响应头都支持这个属性,它通过不同的值 来定义不同的策略
no-store 没有缓存,每次客户端发起请求都会下载完整的响应内容
no-cache 缓存但需验证,每次发出请求时携带新鲜度验证字段,服务端会验证请求中的新鲜度字段,若未过期,返回304,则浏览器使用本地缓存副本
public 表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存
private 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)
max-age=
s-maxage=
....等等(省略不常见的)
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首部,则浏览器可能会试探性的计算出一个最大使用期,作为强缓存时间