一、缓存策略
1 - 缓存策略的分类
根据是否需要向服务器端发起请求,主要分为两大类
- 强缓存:客户端获取一个资源后,服务器端会给这个资源一个缓存时间,在资源的有效缓存时间内,下次请求直接使用缓存,如果不在缓存时间内,则执行比较缓存策略。
- 协商缓存:客户端使用一个资源时,先把资源的缓存数据标识和最后更新时间发送给服务器,由服务器进行校验,检验成功后,返回304状态码标识当前资源可以直接使用缓存资源。
2 - 缓存开始时间
缓存策略都是从第二次请求开始
- 第一次请求资源:服务器端返回资源,并在请求头中添加使用的请求策略
- 第二次请求资源:根据请求参数,击中强缓存,直接返回200并使用缓存数据,否则将缓存标志数据添加到请求头中去请求服务器看是否击中协商缓存,击中则返回304,否则服务器返回新的资源。
二、强缓存
1 - 概念
在缓存数据未失效的情况下,直接使用缓存数据。在network调试工具中可以看到from memory 或者 from disk
2 - 如何判断数据是否失效
在请求资源时,服务器会在响应头上添加跟缓存策略相关的数据来告诉客户端当前缓存数据的有效性。catch-control的优先级高于expires
- HTTP1.0 - Expires:绝对时间
- HTTP1.1 - Cache-Control:相对时间
3 - expires
- 概念:表示绝对时间,即在该时间之前发起的请求都可以直接使用资源,无需请求;
- 缺点1:返回的是服务器端时间,一方面容易在客户端修改时间从而导致缓存时间失效,另一方面客户端和服务器端的时差或误差也容易造成缓存时间不准确。
- 缺点2:如果在到期之前修改了资源内容,客户端是不会知道的
4 - catch-control
表示相对时间,即上一次正确请求资源后的多少秒之内都可以直接使用缓存数据
(1)常用的一些属性值
- private【默认值】:只有客户端可以已经缓存,代理服务器不能进行缓存
- public:所有的内容都可以被缓存
- no-cache:不使用强制缓存,需要和服务器端去验证当前资源的有效性
- no-store:真正意义上的不缓存,即不使用强制缓存也不使用协商缓存
- max-age:当前缓存的最大有效时间
- must-revalidate:超过最大有效时间后必须向服务器端验证资源是否有效
(2)优缺点
- 优点:以时间间隔作为过期时间判断,解决了服务端和客户端时间不准确问题;添加了很多其他的配置值
- 缺点:在有效期内当资源发生修改后,客户端无法知道
三、协商缓存
1 - 概念
协商缓存是由客户端带着一些参数去让服务器决策是返回200或者304;当客户端的强缓存失效或者在请求头中设置了不走强缓存且设置了协商缓存的请求头,则会去服务器端去验证是否命中协商缓存,命中则返回304,没有命中则返回资源。
2 - 如何判断缓存是否新鲜
在请求资源时会在响应头上设置两组数据,Etag的优先级高于Last-Modified
- Last-Modified / If-Modified-since:表示服务器的最后修改时间
Etag / If-None-match:表示服务器资源的唯一标识
3 - Last-Modified/If-Modified-since
(1)验证过程
客户端第一次去请求资源时,服务器通过last-modified告诉客户端该资源的最后一次修改内容,客户端接收到资源和最后修改时间一起记录到缓存数据库中,下次请求相同的资源时,客户端将Last-Modified的值写入请求头的If-Modified-since中,服务器拿到该字段和自己的Last-Modified进行判断,如果相同则直接返回304,反之则返回200并返回资源
(2)缺点只要资源被修改,无论是否是实质性的变化,都会更新
- 如果文件是服务器动态生成的,则得到的时间永远是生成的时间,即使数据没有发生变化也会重新请求,无法达到缓存的一个作用。
4 - Etag/If-None-match
(1)验证过程
整体的验证过程和Last-Modified一致,只是将最后修改时间的对比判断 改 成了当前资源特殊标志的对比(一般是通过hash生成),在服务端进行比对时,将If-Modified-since 修改成了 If-None-match
(2)优点
- 可以更加精准的判断当前资源是否被修改,可以识别一秒内多次修改的情况
(3)缺点
- 计算Etag值需要一定的性能消耗
- 如果Etag的计算方式不一样,回导致浏览器从一台服务器上或得页面内容后到另外一台服务器上验证时Etag不匹配问题