浏览器缓存即http缓存,它可以细分为强制缓存和协商缓存,两者的区别是当浏览器缓存命中时,是否需要向服务器发起请求,询问是否可以使用缓存中的响应资源
相关Headers
Last-Modified/If-Mofified-Since(http1.0)
响应头:Last-Modified:资源最近更新时间,浏览器收到这个响应头后,下次再请求这资源的时候,会带上请求头:If-Modified-Since:保存的是Last-Modified的值。下一次发送请求的时候,会询问服务器在这个时间后还有没有更新,有的话就会返回更新后的响应数据,状态码200,并且浏览器更新缓存,反之返回304状态码。
ETag/If-None-Match(http1.1)
响应头:ETag:资源唯一标识符,由服务器设置,当资源有变化的时候就会重新生成。
请求头:If-None-Match 客户端设置,会将当前ETag发送给服务器,询问这个ETag标记的资源是否有改变,有的话就返回新的资源,否则返回304状态码。
ETag优先级高于Last-Modified。
Expires(1.0)
缓存到期时间,告诉浏览器什么时间缓存失效,这个字段受客户端时间限制,如果客户端时间改了,可能会造成缓存失效。
Cache-Control(1.1)
为了弥补expires的缺陷,出现了Cache-Control,优先级比Expires高. Cache-COntrol的取值:
| 指令 | 作用 |
|---|---|
| public | 表示响应可以被客户端和代理服务器缓存 |
| private | 表示响应只可以被客户端缓存 |
| max-age=30 | 缓存30秒后就过期,需要重新请求 |
| s-maxage=30 | 覆盖max-age,作用一样,只在代理服务器生效 |
| no-store | 不缓存响应 |
| no-cache | 资源被缓存,但是立即失效,下次会发起请求验证资源是否过期(就是协商缓存的意思) |
| max-stale=30 | 30s内,即使缓存过期,也使用该缓存 |
| min-fresh=30 | 希望在30s内获取最新响应 |
请求流程
强制缓存
每次请求的可以再次利用的资源都应该被浏览器缓存起来。强制缓存主要取决于Expires和Cache-Control的max-age字段。
发起请求的时候,先检查Cache-Control字段。校验成功就从浏览器缓存资源,失效的话才检查Expires字段(已过时),校验成功,也可以从浏览器拿到缓存,都失败了就要向服务器发起请求拿数据。
强缓存的目的是减少请求次数
协商缓存
客户端向浏览器发送请求,请求头会携带If-None-Match和If-Modified-Since两个字段,分别保存ETag和Last-Modified的值,服务器根据这两个值判断资源是否更新,没更新就返回304,从浏览器缓存里拿数据,否则返回200,同时携带四个首部,表示资源更新了
启发式缓存
缓存的默认行为(即对于没有 Cache-Control 的响应)不是简单的“不缓存”,而是根据所谓的“启发式缓存”进行隐式缓存。
HTTP 旨在尽可能多地缓存,因此即使没有给出 Cache-Control,如果满足某些条件,响应也会被存储和重用。这称为启发式缓存