缓存的概念分很多种,本次讨论的主要就是前端缓存中的Http缓存。
缓存是怎么回事
前端发送请求主要经历以下三个过程,请求->处理->响应。如果有多次请求就需要重复执行这个过程。
重复请求的过程
以下是一个重复请求的流程图:
从以上的流程图可以看书,如果用户重复请求同一资源的话,会对服务器资源造成浪费,服务器重复读取资源,发送给浏览器后浏览器重复下载,造成不必要的等待与消耗。
缓存读取的过程
缓存读取就是浏览器在向服务器请求资源之前,先查询一下本地缓存中是否存在需要的资源,如果存在,那便优先从缓存中读取。当缓存不存在或者过期,再向服务器发送请求。
如何开启Http缓存并对缓存进行设置,是本次讨论的关键。
缓存的类型
浏览器有如下常见的几个字段:
-
expires: 设置缓存过期的时间
-
private: 客户端可以缓存
-
public: 客户端和代理服务器都可缓存
-
max-age=xxx: 缓存的内容将在 xxx 秒后失效
-
no-cache: 需要使用对比缓存来验证缓存数据
-
no-store: 所有内容都不会缓存,强制缓存,对比缓存都不会触发
-
last-modified: 内容上次被修改的时间
-
Etag: 文件的特殊标识
强制缓存和协商缓存
缓存方法可以分为强制缓存与协商缓存。
从字面理解,强制缓存的方式简单粗暴,给cache设置了过期时间,超过这个时间之后cache过期需要重新请求。上述字段中的expires与cache-control中的max-age都属于强制缓存。
协商缓存根据一系列条件来判断是否可以使用缓存。
强制缓存优先级高于协商缓存
强制缓存
expires
expires给浏览器设置了一个绝对时间,当浏览器时间超过这个绝对时间之后,重新向服务器发送请求。
Expires: Fri, 04 Jan 2019 12:00:00 GMT
这个方法简单直接,直接设定一个绝对的时间 (当前时间+缓存时间)。但是也存在隐患,例如浏览器当前时间是可以进行更改的,更改之后expires设置的绝对时间相对不准确,cache可能会出现长久不过期或者很快就过期的情况。
cache-control: max-age
为了解决expires存在的问题,Http1.1版本中提出了cache-control: max-age,该字段与expires的缓存思路相同,都是设置了一个过期时间,不同的是max-age设置的是相对缓存时间开始往后多久,因此不存在受日期不准确情况的影响。
但是强制缓存存在一个问题,该缓存方式优先级高,如果在过期时间内缓存的资源在服务器上更新了,客服端不能及时获取最新的资源。