缓存的优点:
缺点:
资源如果有更改,会导致客户端不及时更新就会造成用户获取信息滞后
当浏览器去请求某个文件的时候,服务端就在respone header
里面对该文件做了缓存配置。缓存的时间、缓存类型都由服务端控制
浏览器第一次请求时
浏览器后续在进行请求时
从上图可以知道,浏览器缓存包括两种类型,即强缓存(本地缓存)和协商缓存,浏览器在第一次请求发生后,再次请求时
cache-control
)和expires
信息,若命中,直接从缓存中获取资源信息,包括缓存header
信息,本次请求根本就不会与服务器进行通信 请求头信息* Accept: ""
* Accept-Encoding: gzip,deflate
* Accept-Language:zh-cn
* Connection: keep-alive
* Host
* Referer
* User-Agent
来自缓存的响应头的信息
Accept-Ranges: bytes
Cache-Control: max-age= xxxx
Content-Encoding: gzip
Content-length: 3333
Content-Type: application/javascript
Date:xxx
Expires: xxx
Last-Modified:xxx
Server: 服务器
header
字段信息(Last-Modified/If-Modified-Since
和Etag/If-None-Match
),由服务器根据请求中的相关header
信息来比对结果是否协商缓存命中,若命中,则服务器返回新的响应header
信息更新缓存中的对应header
信息,但是并不返回资源内容,它会告知浏览器可以直接从缓存获取,否则返回最新的资源内容类型 | 获取资源形式 | 状态码 |
---|---|---|
强缓存 | 从缓存取 | 200 |
协商缓存 | 从缓存取 | 304 |
强缓存相关的header
字段
强缓存是直接从缓存中获取资源而不经过服务器,与强缓存相关的header
字段有两个
expires
:这是http1.0的规范,它的值为一个绝对时间的 GMT 格式的时间字符串,如Mon, 15 Jun 2029 20:08:12 GMT,如果发送请求的时间在expires之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源cache-control
: max-age=number
,这是http1.1时出现的header信息,主要利用该字段的max-age
值来进行判断,它是一个相对值,资源第一次请求时间和Cache-Control
设定有效期,计算出一个资源过期时间,在拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就能命中缓存,否则就不行,cache-control
除了该字段外,还有下面几个比较常用的设置值no-cache
: 不使用本地缓存,需要使用协商缓存,先与服务器确认返回的响应是否被更改,如果之前中存在ETag,那么请求的时候会与服务器验证,如果资源未被更改,则可以避免重新下载no-store
: 直接禁止浏览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源public
: 可以被所有的用户缓存,包括终端用户和 cdn
等中间代理服务器private
: 只能被终端用户的浏览器缓存,不允许 cdn
等中缓存服务器对其缓存注意
如果cache-control
与expires
同时存在的话,cache-control
的优先级高于expires
协商缓存相关的 header 字段
协商缓存都是由服务器来确定缓存资源是否可用的,所以客户端与服务器端需要某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问,这主要涉及到下面两组 header
字段
这两组搭档都是成对出现的,即第一次请求的响应头带上某个字段(Last-Modified
或 Etag
),则后续请求则会带上对应的请求字段(If-Modified-Since
或 If-Node-Match
),若响应头没有Last-Modified
或Etag
字段,则请求头也不会由对应的字段
Last-Modified/If-Modified-Since
二者的值都是 GMT
格式的时间字符串,具体过程
response
的header
加上Last-Modified
的header
,这个header
表示这个资源在服务器上的最后修改时间request
的header
上加上If-Modified-Since
的header
,这个header
的值就是上一次请求时返回的Last-Modified
的值If-Modified-Since
和资源在服务器上的最后修改时间判断资源是否有变化,如果没有变化则返回 304 Not Modified
,但是不会返回资源内容,如果有变化,就正常返回资源内容,当服务器返回 304 Not Modified
的响应时,response header
中不会再添加 Last-Modified
的header
,因为既然资源没有变化,那么Last-Modified
也就不会改变,这是服务器返回304
的 response header
Last-Modified
的 Header
在重新加载的时候会被更新,下次请求时,If-Modified-Since
会启用上次返回的 Last-Modifed
的值这两个值是由服务器生成的每个资源的唯一标识符,只要资源有变化,这个值就会改变,其判断过程与Last-Modified/If-Modified-Since
类似,与Last-Modified
不一样的是,当服务器返回304 Not Modified
的响应时,由于ETag
重新生成过,response header
中还会把这个ETag
返回,即使这个ETag
跟之前没有变化
既有Last-Modified
又为何有ETag
使用Last-Modified
已经足以让浏览器知道本地的缓存副本是否足够新,那为什么还需要Etag呢,HTTP1.1 中ETag的出现主要时为了解决几个Last-Modified比较难解决的问题
If-Modified-Since
能检查到的粒度时 s 级的,这种修改无法判断(或者说 UNIX
记录 MTIME
只能精确到秒)这时,利用ETag
能够更加准确的控制缓存,因为ETag
时服务器自动生成或由开发者生成对应资源在服务器端的唯一的标识符
Last-Modified
与 ETag
是可以一起使用的,服务器会优先验证ETag
,一致的情况下,才会继续比对Last-Modified
,最后才决定是否返回304
以上就是强缓存与协商缓存的学习介绍,每逢面试必问....重要性,你懂的