对于浏览器缓存,相信很多开发者对它是又爱又恨,一方面,它可以极大地提升用户体验,另一方面,在开发中经常会由于浏览器缓存而展示了‘错误’的东西。那么,浏览器缓存究竟是什么呢?它的内部机制又是怎样的?接下来就让我跟大家分享一下浏览器缓存机制。
一.浏览器缓存概念
简单来说,浏览器缓存就是把一个已经请求过的web资源拷贝一份存储在浏览器中,当下次请求相同的资源时,浏览器会根据缓存机制决定直接使用副本响应访问请求还是再次向服务器发送请求。
如下图所示是我在第二次打开某个网页时的资源请求图,可以看出里面大部分资源是从浏览器直接读取了缓存。
二.浏览器缓存作用
1.加快页面打开速度
2.降低服务器压力
3.减少网络损耗
等等。
三.浏览器缓存机制
浏览器缓存分为 HTML Meta标签控制 与 HTTP头信息控制。
1.HTML Meta标签控制
HTML Meta标签控制 是指在html页面中加入如下标签:
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
上述代码的作用是告诉浏览器当前页面不被缓存。所以每当需要请求该页面时都需要去服务器获取。
但由于仅有部分浏览器支持该标签,并且所有的缓存代理服务器均不支持,所以并未被广泛使用。
2.HTTP头信息控制
HTTP 有一些简单的机制可以在不要求服务器记住有哪些缓存拥有其文档副本的情况下,保持已缓存数据与服务器数据之间充分一致,HTTP 将这些简单的机制成为文档过期和服务器再验证。
(1)文档过期
--Expires 与 Cache-Control
Expires 与 Cache-Control 是服务器端在响应请求时用来说明当前资源的有效期。Expires 规定了缓存的失效时间,而 Cache-Control 是通过 max-age 来规定缓存的有效时间,如下图所示:
Expires 是 HTTP 1.0 的字段,而 Cache-Control 是 HTTP 1.1 的字段,当 Expires 与 Cache-Control 同时存在时,Cache-Control 的优先级要高于 Expires。
Cache-Control 再介绍:
Cache-Control 指定了请求和响应遵循的缓存机制。
下图列出了 Cache-Control 常用字段:
需要注意的是,在请求头中加上了 Cache-Control:no-cache 的作用是指跳过文档过期时间的验证而直接进行服务器再验证,而 Cache-Control:no-store 是指资源禁止被缓存。关于 Cache-Control 的具体情况,我会在之后推文中做更详细的介绍。
(2)服务器再验证
--Last-Modified / If-Modified-Since
Last-Modified 是服务器端在响应请求时用来说明当前资源的最后修改时间。If-Modified-Since 是指在文档过期验证中发现资源过期时,并且发现该资源具有 Last-Modified 属性,则再次向服务器端发送对该资源的请求时会带上 If-Modified-Since 属性,值为该资源 Last-Modified 属性的值。
当服务器端接收到带有 If-Modified-Since 属性的请求时,则会将 If-Modified-Since 属性的值与被请求资源的最后修改时间做对比。如果相同,说明资源没有新的修改,则响应 HTTP 304,浏览器会继续使用原先保存的该资源的副本;如果最后修改时间比较新,则说明资源被修改过,则响应 HTTP 200,并且返回最新的资源。
--Etag / If-None-Match
Etag 是服务器端在响应请求时用来说明当前资源在服务器端的唯一标识。If-None-Match 是指在文档过期验证中发现资源过期时,并且发现该资源具有 Etag 属性,则再次向服务器端发送请求该资源时会带上 If-None-Match 属性,值为该资源 Etag 属性的值。
当服务器端接收到带有 If-None-Match 属性的请求时,则会将 If-None-Match 属性的值与被请求资源的唯一标识做对比。如果相同,说明资源没有新的修改,则响应 HTTP 304,浏览器会继续使用原先保存的该资源的副本;如果不同,则说明资源被修改过,则响应 HTTP 200,并且返回最新的资源。
既生 Last-Modified 何生 Etag?
你可能会觉得有点困惑,似乎 Last-Modified / If-Modified-Since 与 Etag / If-None-Match 的作用是一样的,那么当他们都同时存在时是什么情况呢?
事实上,当两者同时存在时,Etag / If-None-Match 的优先级要高于 Last-Modified / If-Modified-Since,HTTP 1.1 中 Etag 的出现主要是为了解决几个 Last-Modified 比较难解决的问题:
- Last-Modified 标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内被修改多次的话,它将不能准确标注文件的修改时间;
- 如果某些文件会被定期生成,但有时内容并没有任何变化,但 Last-Modified 却改变了,导致文件没法使用缓存;
- 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形;
网友评论