什么是缓存
缓存是浏览器的一种机制,可以把请求过的web资源(html、css、js、图片等)拷贝一份副本存储在浏览器中,并根据请求配置选择是否使用该副本。
缓存作用
减少 带宽消耗降低服务器压力减少 延迟,使页面的打开速度更快,增加用户体验根据不同的划分规则,缓存可以分为以下几种:
本文只介绍浏览器的缓存机制。
浏览器缓存规则定义位置
可以在 HTTP协议头 和HTML页面的 meta标签 中定义。
meta标签定义:
<!- Pragma 是 http1.0 版本中给客户端设定缓存方式之一 -> <meta http-equiv="Pragma" content="no-cache">
上述代码的含义:浏览器当前页面不被缓存,每次访问都向服务器请求。
http协议头定义:
与缓存有关的消息报头有Expires,Cache-Control,Last-Modified,If-modified-since,Etag,If-none-match 等。
缓存分类
根据是否需要向服务器发送资源请求,分为 强缓存 和 协商缓存。强缓存意味着强制使用缓存,协商缓存意味着每用一次缓存都要协商一次。 强缓存和协商缓存都允许使用情况下,优先强缓存。
强缓存
强缓存的控制字段:
HTTP1.0:ExpiresHTTP1.1 :Cache-Control判断过程:请求再次发起 -> 浏览器根据 expires 和 cache-control 判断目标资源是否命中"强缓存" -> 若命中,直接从缓存获取资源,不再与服务器发生通讯。
如果cache-control与expires同时存在,以cache-control为主,继续使用 expires 的目的就是向下兼容。
Expire已经被Cache-Control替代,原因在于Expires依赖于本地时间,它控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,那么如果客户端与服务端的时间因为某些原因(例如时区不同;客户端和服务端有一方的时间不准确;用户修改了本地时间)发生误差,那么强制缓存则会直接失效。
Cache-Control取值: 在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存,主要取值为: public:所有内容都将被缓存(客户端和 服务器都可缓存) private:所有内容只有客户端可以缓存,Cache-Control的默认取值 no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定 no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存 max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效 must-revalidate: 强制浏览器严格遵守你设置的cache规则 proxy-revalidate: 强制proxy严格遵守你设置的cache规则 协商缓存 协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有以下两种情况:协商缓存生效,返回304 && 协商缓存失效,返回200和请求结果。 协商缓存流程: 协商缓存的控制字段: Last-Modified 与 If-Modified-Since Last-Modified 是服务器响应请求时,返回该资源文件在服务器最后被修改的时间 流程: 弊端: Last-Modified 无***确感知文件的变化,譬如说,文件的编辑时间修改了而内容没有修改,或者修改文件速度太快,几毫秒就改一次文件,If-Modified-Since 只能检测秒级的变化.为了解决这个问题,Etag 作为 Last-Modified 的升级版,因时而生。Etag 是通过标识字符串来辨别文件内容是否发生修改的,文件内容不一致才会生成新的标识字符串,这就弥补了 Last-Modified 时间戳的不足,通过 Etag 可以精准的感知文件的变化。 Etag && If-None-Match Etag 是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成) 流程: 弊端: Etag的生成需要服务器付出额外的开销,会影响服务端性能。 Etag 并不能替代 Last-Modified,只能作为 Last-Modified 的补充和强化存在,当 Etag 和 Last-Modified 同时出现时,以 Etag 为准。 整个缓存机制的流程图: 不能被缓存的请求 用户操作行为与缓存 浏览器中的操作对缓存的影响