问题背景:日常开发当中,经常碰到代码提测部署后,刷新页面但新发布内容未更新到最新版本,针对这个问题,下面分成几个部分与大家进行探讨与研究:
- 解决页面内容不更新的方式有几种,产生问题的原因是什么?
- 缓存的种类,强缓存与协商缓存。
- http缓存的整个流程
- 每种操作能够触发的强缓存和协商缓存对比。
解决页面刷新
通常我们在打开一个url,或者更新浏览器页面代码,包括以下几种方式:
- 页面的前进后退;
- 打开新的url链接跳转;
- 地址栏回车;
- F5 or(command+R)刷新;
- Ctrl+F5 or (Shift+command+R);
- Shift+command+R,在url+参数。
在1-5操作的过程中,时常会发现提测的内容,没更新过来,那么是怎么导致这种现场呢?平时的经验在解决该类问题的时候指导我们,各类缓存策略的使用,是导致请求不到最新版本的直接原因,通常这个时候产品或者后端问到后,大部分会说:清一下缓存!!! 那么为什么清理了缓存问题就解决了呢?缓存到底有哪些类型?每种缓存又具有哪些特点?哪些操作,会触发哪些类型的缓存?这些疑问,都指向了缓存相关的技术知识,弄清楚缓存,就是弄清楚产生问题的根本原因,那么如何着手解决也就有了思路。
缓存的种类,*http缓存之强缓存与协商缓存
http缓存:http缓存指的是, 当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源。
强缓存
浏览器在第一次向服务器发送请求时,若服务器觉得该资源需要缓存,这时服务器就会在响应头response-header 里面添加一个cache-control,如设置max-age,这样浏览器就会在本地缓存中存下相应的文件。
在浏览器下一次请求同样的文件时,浏览器就会去检查 max-age 有没有过期,如果没有过期就直接从本地缓存里获取资源,不会向服务器去发请求,这样就会提升页面的加载速度。如果max-age过期了,那么浏览器又会向第一次一样去向浏览器发送请求。
这种方式页面的加载速度是最快的,性能也是很好的,但是在这期间,如果服务器端的资源修改了,页面上是拿不到的,因为它不会再向服务器发请求了。这种情况就是我们在开发种经常遇到的,比如你修改了页面上的某个样式,在页面上刷新了但没有生效,因为走的是强缓存,所以Ctrl + F5之后就好了。
from memory cache代表使用内存中的缓存,from disk cache则代表使用的是硬盘中的缓存,浏览器读取缓存的顺序为memory –> disk。在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。
强制缓存的header属性(Pragma/Cache-Control/Expires)
浏览器在请求某一资源时,会先获取该资源缓存的 header 信息,判断是否命中强缓存(cache-control 和 expires 信息),若命中直接从缓存中获取资源信息,包括缓存 header 信息,本次请求根本就不会与服务器进行通信。
expires:这是 http1.0 时的规范;它的值为一个绝对时间的GMT格式的时间字符串,如Mon, 10 Jun 2015 21:31:12 GMT,如果发送请求的时间在expires之前,那么本地缓存始终有效,否则就会发送请求到服务器来获取资源。 cache-control:这是 http1.1 时出现的header信息,主要是利用该字段的max-age值来进行判断,它是一个相对值;资源第一次的请求时间和Cache-Control设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就能命中缓存,否则就不行;cache-control 的设置与否在于服务器,都是在服务器端设置的,前端不需要做任何事情
协商缓存(对比缓存)
浏览器第一次请求的时候,若服务器使用了协商缓存的策略,则它会返回资源和资源标识,并且浏览器将返回的资源存储到本地缓存。
当浏览器再次请求该资源时,浏览器向服务器发送请求和资源标识,服务器这时就会去判断当前请求的资源浏览器本次缓存的版本跟服务器里面资源最新的版本是否一致:
- 如果版本一致,服务器返回 304 状态码,重定向让浏览器直接在本地缓存里拿资源;
- 如果版本不一致,服务器返回 200 状态码、最新的资源以及新的资源标识,浏览器更新本地缓存。
资源标识:
-
Last-Modified/If-Modified-Since:指资源上一次修改的时间
-
Etag/If-None-Match:资源对应的唯一字符串
服务器会为每个资源生成一个唯一的标识字符串,只要文件内容不同,它们对应的 Etag 就是不同的;If-Modified-Since能检查到的精度是s级的,某些服务器不能精确的得到文件的最后修改时间,我们编辑了文件,但文件的内容没有改变。因为服务器是根据文件的最后修改时间来判断的,导致重新请求所以才出现了Etag,Etag对服务器也有性能损耗 Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
(一)Last-Modified
在浏览器第一次请求时,服务器返回资源和资源标识符Last-Modified(在响应头中)
在后续请求中,浏览器就会在请求头带上资源标识 If-Modified-Since 发起请求,If-Modified-Since的值就是上一次请求时返回的 Last-Modified 的值,这时在服务器就会去对比If-Modified-Since 和 Last-Modified 的值判断是否是最新资源。
(二)ETag
其流程跟Last-Modified 类似。
参考原文链接:blog.csdn.net/weixin_4595…