1.http缓存分为强缓存和协商缓存
强缓存
: 强缓存命中不会发送请求到服务器端,直接从本地缓存中获取资源,状态码200 ( from cache )
协商缓存
:协商缓存会发送请求到服务器,服务器通过请求头部字段来验证资源是否命中协商缓存,如果命中,则返回状态码304 ( not modified )
,通知浏览器从缓存中获取资源
2.根据响应头部的字段确定浏览器缓存策略
2.1Cache-Control
- no-cache: 资源可以被缓存,但立即过期,下次访问必须验证资源有效性
- max-age: 缓存资源,在指定时间后过期 (单位秒)
- no-store: 资源不会被缓存
- public: 资源可以被浏览器和代理服务器缓存
- private: 资源只能被浏览器缓存
2.2 Progma
- 只有一个值
no-cache
, 功能和Cache-Control:no-cache
一样
2.3 Expires
- expires是缓存到期时间,以服务器时间为参考,优先级比Cache-Control: max-age低
- 在一些场景中必须避免浏览器缓存,推荐的做法是设置请求头(Cache-Control: no-cache, no-store, must-revalidate)
3强缓存命中条件
- 请求头不包括Pragma字段
- 响应头部Cache-Control中不包括no-cache,no-store
- 响应头部max-age或者Expires大于请求时间
- 没有设置以上信息, 短时间内多次请求。在启发式算法时间内, 取响应头(Date-Lst-Modefied) *0.1作为缓存有效时间,在这个时间内,会命中强缓存
4命中协商缓存
4.1 Last-Modified/If-Modified-Since
服务器响应资源的时候返回一个头部字段 Last-Modified
,代表该资源最后修改时间
当浏览器再次向服务器请求该资源时
会传送 If-Modified-Since
信息,意为该时间之后文件是否有被修改过
服务器将这个请求时间与本地资源实际最后修改时间做对比,如果文件没有被修改,则返回状态码 304
,通知浏览器从缓存中读取资源文件。
如果If-Modified-Since的时间比服务器当前时间(当前的请求时间request_time)还晚,会认为是个非法请求
4.2 ETag/If-None-Match
ETag
是一个响应首部字段,它是根据资源内容生成的一段hash字符串,标识资源的状态,
由服务端产生。当浏览器再次向服务器请求该资源时
会传送 If-None-Match
字段
服务器收到请求后,拿 If-None-Match
字段的值与资源的实际 ETage 值进行比较
若相同,则命中协商缓存,返回状态码 304
。
ETag
优先级比 Last-Modified
高,同时存在时会以ETag
为准。
那已经有了 Last-Modified
机制,为什么要引入 ETage
机制呢?
- 某些服务器不能精确得到资源的最后修改时间,这样就无法通过最后修改时间判断资源是否更新
- 如果资源修改非常频繁,在秒以下的时间内进行修改,而
Last-Modified
只能精确到秒 - 一些资源的最后修改时间改变了,但是内容没改变,使用
ETag
就能判别出资源内容是否被修改