一、浏览器缓存类型
浏览器缓存分为强缓存和协商缓存。
一般来说,两者的关系是:
- 先强缓存,服务器先从http头信息来判断是否命中强缓存,如果命中则直接加在缓存中的资源,并不会将请求发送到服务器。
- 再协商缓存,浏览器会将资源加载请求发送到服务器。服务器来判断浏览器本地缓存是否失效。若可以使用,则服务器并不会返回资源信息,浏览器继续从缓存加载资源。
- 不命中,服务器会将完整的资源返回给浏览器,浏览器加载新资源,并更新缓存。
二、强缓存
命中强缓存时,浏览器并不会将请求发送给服务器。

强缓存是利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。
Expired(HTTP1.0产物,优先级低)
-
简介
缓存过期时间,用来指定资源到期的时间,是一个服务端发送的具体时间点。 -
缺点
由于失效时间是一个绝对时间,所以当客户端本地时间被修改以后,服务器与客户端时间偏差变大以后,就会导致缓存混乱。
❗Tips:
HTTP1.0中通过Pragma 控制页面缓存,通常设置的值为no-cache,例如<META HTTP-EQUIV="Pragma" CONTENT="no-store">
,由于不过这个值不这么保险,通常还加上Expires置为0来达到目的。
Cache-Control (HTTP1.1产物,优先级高)
-
简介
Cache-Control是一个相对时间,例如Cache-Control:3600,代表着资源的有效期是3600秒。由于是相对时间,并且都是与客户端时间比较,所以服务器与客户端时间偏差也不会导致问题。
Cache-Control与Expires可以在服务端配置同时启用或者启用任意一个,同时启用的时候Cache-Control优先级高。
(也就是,Cache-Control过期的时候,Expired没过期也默认强缓存失败.) -
字段
Cache-Control 可以由多个字段组合而成,主要有以下几个取值:
- max-age:时间长度,单位为s
- s-maxage:同 max-age,覆盖 max-age、Expires,但仅适用于共享缓存,在私有缓存中被忽略。
- public:共享缓存,浏览器和缓存服务器都可以缓存页面信息;
- private:私有缓存,表明响应只能被单个用户(可能是操作系统用户、浏览器用户)缓存,不能被代理服务器缓存。
- no-cache:强制所有缓存了该响应的用户,在使用已缓存的数据前,发送验证请求到服务器。不是字面意思上的不缓存。
- no-store:禁止缓存,每次请求都要向服务器重新获取数据。
- must-revalidate:指定如果页面是过期的,则去服务器进行获取。比较少用。
三、协商缓存
若未命中强缓存,则浏览器会将请求发送至服务器。服务器根据http头信息中的Last-Modify/If-Modify-Since或Etag/If-None-Match来判断是否命中协商缓存。如果命中,则http返回码为304,浏览器从缓存中加载资源。
Last-Modify/If-Modify-Since (优先级低)
浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间。
当浏览器再次请求该资源时,发送的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。
ETag/If-None-Match (优先级高)
与Last-Modify/If-Modify-Since不同的是,Etag/If-None-Match返回的是一个校验码。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。ETag值的变更则说明资源状态已经被修改。服务器根据浏览器上发送的If-None-Match值来判断是否命中缓存。

Why Etag?
- Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
- 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
- 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。
四、注意!
普通刷新会放弃强缓存,Ctrl+F5强制刷新会放弃协商缓存。
五、总结
记住:Cache-Control > Expired,Etag > Last-Modify。
大于号指的是,当两者在场时,一方的决定能够覆盖另一方。
强缓存 > 协商缓存。
大于号指的是,当强缓存不能缓存的时候,再判断协商缓存。
-
第一次请求时
第一次请求时
-
再次请求时
再次请求时
网友评论