什么是Http缓存
http缓存是客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源。
注:http缓存只能缓存get请求的资源
http缓存的分类
http缓存可以分为2大类
- 强制缓存
- 协商缓存
强制缓存只要满足条件就会使用客户端的缓存,如下图:
协商缓存(对比缓存)是不管如何情况都会再去请求服务端的,下文会说到为什么:
强制缓存
跟强制缓存有关的请求头有三个:pragma
、cache-control
、Expires
。
强制缓存有一个缺点,就是在符合条件下,哪怕服务端有更新,也获取不到服务端的新内容。
pragma
http1.0的规则,http1.1已废弃,目前仅支持 no-cache(禁用缓存),优先级最高。
cache-control
http1.1新增,目前强缓存用的最多的规则,http
1.0不适用,常用有五个属性值,优先级中等。
属性值:
- private:特定客户端可以缓存(只能同一用户账号)
- public:客户端和代理服务器都可以缓存
- max-age=xxx:缓存的内容xxx秒,xxx秒后缓存过期,max-age=2000,2000秒后需要再有请求就会从服务端拉取
- no-cache:不直接使用缓存,使用协商缓存
- no-store:不缓存,每次都重新从服务端拉取
expires
http1.0的,规定到期时间,expires=“Fri, 16 Aug 2018 09:16:20 GMT” (GMT时间)过了这个时间采取服务端请求,但是假如客户端改时间的话,这个规则就没用了,在http1.1中也有,但是用的很少,优先级最低。
协商缓存
当强制缓存的cache-control为no-cache,或者expires过期的时候就会自动使用协商缓存。
协商缓存返回2种状态码,200代表返回了内容,304代表可以继续使用缓存。
协商缓存主要是一下2个规则组:Last-Modified / If-Modified-Since
、Etag / If-None-Match
Last-Modified / If-Modified-Since
当第一次访问服务器某个资源的时候,服务器在reponse header 中会返回 Last-Modified ,例如 Last-Modified=“Fri, 16 Aug 2018 09:16:20 GMT”,代表文件最后一次更新时间。
第二次访问这个资源的时候,客户端的请求头上会带上 If-Modified-Since这个属性,值是服务端返回的Last-Modified这个时间。
因此服务端会做对比,对比文件最后修改的时间和客户端传上来的时候:
- 时间相同:返回的304,客户端使用缓存
- 时间不同:返回新的数据,返回200,返回新的Last-Modified
Last-Modified 基于http1.0,但是由于Last-Modified只能精确到秒,因此在1秒钟之内改动很多次,是无法捕获到的,因此在http1.1中加入了Etag。
Etag / If-None-Match
客户端第一次请求服务端的时候,服务端会返回当前资源的Etag,即当前资源唯一表示,例如:Etag=W/“8131a4fb85394266fb1”。
下一次在请求的时候,请求头就会加上 If-None-Match=(Etag)所返回的信息,服务端就会进行对比,返回304 或者 200。
Etag基于http1.1,Etag在文件进行微小改动都能发现,因此比Last-Modified更具有准确性,而且比Last-Modified优先级要高。
总结
对于强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行比较缓存策略。
对于协商缓存,将缓存信息中的Etag和Last-Modified通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。