HTTP缓存
引言 什么是缓存
通过url请求后台资源即慢,又比较耗流量,HTTP协议为我们提供了控制缓存部分以使Http客户端可以缓存和重用以前获取的资源,从而优化性能,提升体验。简单来说http缓存就是客户端缓存,将一些服务器上的静态文件(css,js,图片等)保存到本地,然后下次在次加载这个文件时根据http缓存方式,不去服务器端读取,而是直接在本地读取。
我们先来看一下在http报文中相关首部的字段
请求报文和响应报文都能用上的字段
字段 | 说明 |
---|---|
Cache-control | 控制是否被缓存 |
pragma | http1.0版本,值为no-cache时禁止缓存 |
请求中(Request Headers)字段
字段 | 说明 |
---|---|
If-Match | 比较ETag是否一致 |
If-None-Match | 比较ETag是否一致 |
If-Modified-Since | 比较资源最后更新时间是否一致 |
If-UnModified-Since | 比较资源最后更新时间是否一致 |
响应中(Response Headers)字段
字段 | 说明 |
---|---|
ETag | 匹配资源信息 |
Last-Modified | 文件最后修改的时间 |
Expires | http1.0的属性,设置过期时间 |
一 缓存策略
1.缓存存储策略
用来确定 HTTP 响应内容是否可以被客户端缓存,以及可以被哪些客户端缓存。 利用属性Cache-Control 属性设置文件是否被缓存,其中常用的属性有public private max-age no-catch no-store其中前四种可以将文件缓存,而no-store 文件将不会被缓存,为什么是可能呢? 因为文件是有新鲜度(也就是是否过期)的,如果文件超过了新鲜度呢,接下来就要说缓存过期策略了
2. 缓存过期策略
客户端用来确认存储在本地的缓存数据是否已过期,进而决定是否要发请求到服务端获取数据
既然文件缓存可以过期,那么就应该存在一个过期时间然后有一个字段去记录这个过期时间,在http1.0中用Expires来记录这个过期时间当超过这个有效时间后,本地缓存就作废了,就必须去服务器再次请求,不过在HTTP1.1中增加了Cache-Control 可以设置max-age来设置过期时间且Cache-Control优先级高于Expires
但是缓存过期了,客户端的缓存一定不能用了吗?答案是否定的,接下来就是要说的缓存对比策略
3. 缓存对比策略
将缓存在客户端的数据标识发往服务端,服务端通过标识来判断客户端 缓存数据是否仍有效,进而决定是否要重发数据。
客户端检测到数据过期或浏览器刷新后,往往会重新发起一个 http 请求到服务器,服务器此时并不急于返回数据,而是看请求头有没有带标识( If-Modified-Since、If-None-Match)过来,如果判断标识仍然有效,则返回304告诉客户端取本地缓存数据来用即可(这里要注意的是你必须要在首次响应时输出相应的头信息(Last-Modified、ETags)到客户端)。至此我们就明白了上面所说的本地缓存数据即使被认为过期,并不等于数据从此就没用了的道理了。
缓存的策略大致就是 通过Cache-Control或者是Expires设置本地缓存,当缓存过期后请求后台,后台根据Etag或If-Modified-Since 来判断当前缓存是否可用,可用则返回一个304状态吗,继续用这个缓存,不可用就会重新加载这个文件
二 强缓存与协商缓存
1.强缓存
浏览器在第一次请求发生后,再次请求时:浏览器在请求某一资源时,会先获取该资源缓存的header信息,判断是否命中强缓存(cache-control和expires信息),若命中直接从缓存中获取资源信息,包括缓存header信息;本次请求根本就不会与服务器进行通信
2.协商缓存
如果没有命中强缓存,浏览器会发送请求到服务器,请求会携带第一次请求返回的有关缓存的header字段信息(Last-Modified/If-Modified-Since和Etag/If-None-Match),由服务器根据请求中的相关header信息来比对结果是否协商缓存命中;若命中,则服务器返回新的响应header信息更新缓存中的对应header信息,但是并不返回资源内容,它会告知浏览器可以直接从缓存获取;否则返回最新的资源内容;
3.强缓存与协商缓存的区别
相同点: 都是从缓存中读取数据
不同点: 强缓存不会请求服务器,而协商缓存同过访问服务器来告知缓存是否可用,强缓存返回状态吗200 (from cache) 协商缓存 返回304 (not modified)
如果你看了上面的还是蒙蒙的那么请看下面,当我们第一次请求时打开network,我们将看到下图
当我们第一次请求某个网页时所有请求返回状态码均为200
当我们再次刷新时可以看到状态码变成了304,和200 size变成from cache
当状态码为200时我们点进去可以看到 属性cache-control:max-age属性 和 Expires 属性 可以看出时间均没过期,也就是这是个强缓存,这个文件不会请求服务器
当状态码为304时可以看到max-age=0也就是说会请求服务器,和服务器协商,然后服务器根据Eage或者 If-Modified-Since 来判断是否继续使用该缓存,如果判断成功,那么返回状态码304,并且继续使用该缓存,失败则重新加载文件
最后贴一张HTTP缓存的流程图