缓存主要解决的问题
- 冗余的数据传输
- 带宽瓶颈
- 瞬间拥塞
- 距离时延
缓存的分类
1、强缓存
强制缓存如果生效,不需要再和服务器发生交互,而弱缓存(协商缓存,对比缓存)不管是否生效,都需要与服务端发生交互
Cache-Control(HTTP1.1,相对值)/Expires(HTTP1.0,绝对值)
Expires是HTTP/1.0的产物 ,设置它主要是为了向下兼容
// http response Cache-Control: max-age=600 // 单位是秒 Expires: Mon, 18 Jun 2018 13:37:33 GMT // 格林乔治时间,在这个时间之后过期复制代码
2、弱缓存/协商缓存/对比缓存
对比缓存,顾名思义,需要进行比较判断是否可以使用缓存。 浏览器第一次请求数据时,服务器会将缓存标识与数据一起返回给客户端,客户端将二者备份至缓存数据库中。 再次请求数据时,客户端将备份的缓存标识发送给服务器,服务器根据缓存标识进行判断,判断成功后,返回304状态码,通知客户端比较成功,可以使用缓存数据。
Last-Modified/If-Modified-Since:Last-Modified是标识文件在服务器上的最近更新时间。下次请求时,如果文件缓存过期,浏览器通过If-Modified-Since字段带上这个时间,发送给服务器,由服务器比较时间戳来判断文件是否有修改。如果没有修改,服务器返回304告诉浏览器继续使用缓存;如果有修改,则返回200,同时返回最新的文件。
// http response header: Last-Modified:Mon, 07 Nov 2016 07:51:11 GMT // http request header: If-Modified-Since:Mon, 07 Nov 2016 07:51:11 GMT复制代码
Etag:ETag的值为服务器对请求的资源的内容按照hash算法计算的一个值,当内容发生改变的时候,这个值会相应的改变。
一些资源文件会周期性的更改,但是内容并不会变,仅仅只改变了其修改时间,这个时候我们并不希望客户端每次都从服务器获取新鲜的资源,而Etag的计算则会保持一致; 某些文件修改非常频繁,GMT时间单位只能精确到秒级,这种文件的验证会出现问题; 某些服务器对文件的计算时间不够精确,存在偏差;
// http response header:ETag: 16e36-540b1498e39c0// http request header:If-None-Match: 16e36-540b1498e39c0复制代码
整体控制缓存是否开启:
Pragma: no-cache //请求头中去掉If-Modified-Since和If-None-Match。复制代码
如何刷新浏览器是最好的?
windows下Ctrl(Mac OS下的command) + R或者F5,即为正常的刷新行为,强缓存和协商缓存都会去验证。 Ctrl + shift + R或者Ctrl + F5或者在devtool的Network中disable cache都会在请求首部加上Cache-Control: no-cache和Pragma: no-cache首部,并且清除掉Etag和Last-Modified首部,从而达到硬性重新加载的效果,即跳过缓存验证。 最后一项则会在上一项的基础上把在内存或者磁盘的缓存全部给清除掉。