缓存机制:
浏览器缓存是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档
浏览器缓存主要指HTTP的缓存–即协议层,协议层缓存可以被分为强制缓存和协商缓存。
强制缓存(Expires或 Cache-Control)
HTTP1.0 Expires:到期时间,【绝对时间】—服务器时间+缓存有效时间
缺点:如果客户端修改了本地时间或本地时间和服务器时间不一致
HTTP1.1 Cache-Control:最大有效时间,【相对时间】
使用相对时间的话,即使本地时间与服务器时间不一致,也不会导致缓存失效。
下面列举一下Cache-Control的字段可以带的值:
- max-age:最大有效时间
- s-maxage:同max-age,但是仅用于共享缓存,如CDN缓存
- public:客户端和代理服务器都可缓存,默认设置
- private:只有浏览器能缓存了,中间的代理服务器不能缓存
- no-cache:无跳过当前的强缓存,发送HTTP请求,即直接进入协商缓存阶段。
- no-store:非常粗暴,不进行任何形式的缓存
协商缓存(Last-Modified或 Etag)
强缓存失效后,进入协商缓存,浏览器缓存中获取对应的数据标识tag,然后向服务器发送请求,确认数据是否更新,如果更新,则返回新数据和新缓存;反之,则返回304状态码,告知客户端缓存未更新,可继续使用。
Etag:该字段存储的是文件的特殊标识(一般都是hash生成的),服务器存储着文件的Etag字段,可以在与每次客户端传送If-no-match的字段进行比较。
如果相等,则表示未修改,响应304;反之,则表示已修改,响应200状态码,返回数据。
Last-Modified:服务器告诉客户端,资源最后一次修改的时间。
- If-Modified-Since:再次请求时,请求头中带有该字段,服务器会将If-Modified-Since的值与Last-Modified字段值进行对比,
如果相等,则表示未修改,响应304状态码,告诉客户端可继续使用缓存;反之,则表示修改了,响应200状态码,返回数据。
- 缺陷:
如果资源更新的速度是秒以下单位,那么该缓存是不能被使用的,因为它的时间单位最低是秒。
如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能没有变化,所以起不到缓存的作用。
两者对比:
在精准度上,ETag优于Last-Modified。优于 ETag 是按照内容给资源上标识,因此能准确感知资源的变化。而 Last-Modified 就不一样了,它在一些特殊的情况并不能准确感知资源变化,主要有两种情况:
编辑了资源文件,但是文件内容并没有更改,这样也会造成缓存失效。
Last-Modified 能够感知的单位时间是秒,如果文件在 1 秒内改变了多次,那么这时候的 Last-Modified 并没有体现出修改了。
在性能上,Last-Modified优于ETag,也很简单理解,Last-Modified仅仅只是记录一个时间点,而 Etag需要根据文件的具体内容生成哈希值。
另外,如果两种方式都支持的话,服务器会优先考虑ETag。
补充:一些浏览器行为会造成什么样的结果?
刷新网页:直接读取缓存,如果缓存失效,再找服务器。
F5手动刷新网页:浏览器会认为缓存失效,请求服务器时带上Cache-Control:max-age:0字段,询问浏览器缓存是否失效。
Ctrl+F5强制刷新网页:浏览器会忽略缓存,请求服务器时带上Cache-Control:no-cache字段,重新请求数据。
以上就是我们常说的浏览器缓存,当然,基本都是服务端配置。缓存的目的是减少请求,减轻服务器的压力,对于小型网站来说也许不是必须的,但是你可以看一下淘宝、京东的网站页面,打开浏览器控制器,就会发现,这是大型网站的必配。