只见正门五间,上面桶瓦泥鳅脊;那门栏窗隔皆是细雕新鲜花样,并无朱粉涂饰;一色水磨群墙,下面白石台阶,凿成西番花草样;左右一望皆雪白粉墙,下面虎皮石随势砌去,果然不落富丽俗套。
-
Web 缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 缓存)、浏览器缓存。
-
浏览器缓存也包含很多内容:
HTTP 缓存
、cookie
、localstorage
、sessionStorage
、离线缓存(application cache)
、Web SQL
、indexDB
。这里我们只讨论 HTTP 缓存相关内容。
HTTP缓存的分类:
浏览器缓存分为强缓存
和协商缓存
,浏览器加载一个页面的简单流程如下:
- 浏览器先根据这个资源的http头信息来判断是否命中强缓存。如果命中则直接加在缓存中的资源,并不会将请求发送到服务器。
- 如果未命中强缓存,则浏览器会将资源加载请求发送到服务器。服务器来判断浏览器本地缓存是否失效。若可以使用,则服务器并不会返回资源信息,浏览器继续从缓存加载资源。
-
如果未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器加载新资源,并更新缓存。
强制缓存与协商缓存请求数据的流程.jpg
1.强制缓存
对于强制缓存来说,响应header中会有两个字段来标明失效规则(Expires/Cache-Control)
- HTTP缓存主要通过meta标签来定义:
<meta http-equiv="Expires" content="Mon, 20 Jul 2013 23:00:00 GMT" />
<meta http-equiv="cache-control" content="no-cache">
Expires
Expires的值为服务端返回的到期时间,即下一次请求时,请求时间小于服务端返回的到期时间,直接使用缓存数据。不过Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。另一个问题是,到期时间是由服务端生成的,但是客户端时间可能跟服务端时间有误差,这就会导致缓存命中的误差。所以HTTP 1.1 的版本,使用Cache-Control替代。
Cache-Control
- max-age=xxx :单位s,缓存内容将在xxx秒后失效,该选项只有HTTP1.1可用,并如果和last-Modified一起使用时,优先级较高。
- public : 所有内容都将被缓存(客户端和代理服务器都可储存)。
- private : 内容只缓存到私有缓存中(仅客户端可缓存,代理服务器不可)。
- no-cache : 协商缓存。
- no-store : 禁止缓存,每次请求都要向服务器重新获取数据。
2.协商缓存
![](https://img.haomeiwen.com/i7900170/4bb635c2b521cc71.jpg)
![](https://img.haomeiwen.com/i7900170/28531cda68b9f91a.jpg)
通过两图的对比,我们可以很清楚的发现,在协商缓存生效时,状态码为304,并且报文大小和请求时间大大减少。原因是,服务端在进行标识比较后,只返回header部分,通过状态码通知客户端使用缓存,不再需要将报文主体部分返回给客户端。
对于对比缓存来说,缓存标识的传递是我们着重需要理解的,它在请求header和响应header间进行传递,一共分为两种标识传递:
1.Last-Modified / If-Modified-Since
Last-Modified
:
服务器在响应请求时,告诉浏览器资源的最后修改时间。
![](https://img.haomeiwen.com/i7900170/a5de69d82bbf6acb.png)
If-Modified-Since
:
再次请求服务器时,通过此字段通知服务器上次请求时,服务器返回的资源最后修改时间。
服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。
若资源的最后修改时间大于If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码200;
若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。
![](https://img.haomeiwen.com/i7900170/bdfd66ef5992b77f.png)
2.Etag / If-None-Match(优先级高于Last-Modified / If-Modified-Since)
Etag
:
服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。
![](https://img.haomeiwen.com/i7900170/d560babc3535240a.png)
If-None-Match
:
再次请求服务器时,通过此字段通知服务器客户段缓存数据的唯一标识。
服务器收到请求后发现有头If-None-Match 则与被请求资源的唯一标识进行比对,
不同,说明资源又被改动过,则响应整片资源内容,返回状态码200;
相同,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。
![](https://img.haomeiwen.com/i7900170/9580b3f3c77f0896.png)
既生Last-Modified何生Etag?
你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:
- Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
- 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
- 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
总结:
![](https://img.haomeiwen.com/i7900170/2624e1074090ade1.png)
![](https://img.haomeiwen.com/i7900170/210de7511c43ea6e.png)
参考:
https://www.cnblogs.com/ranyonsue/p/8918908.html
http://www.cnblogs.com/chenqf/p/6386163.html
网友评论