什么是HTTP缓存
缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。
HTTP 缓存机制就是,通过配置 HTTP 响应头来告诉浏览器是否应该对请求的资源进行缓存、缓存多长时间、缓存是否过期的一种机制。
缓存的优缺点
缓存的优点:
- 减少了不必要的数据传输,节省带宽
- 减少服务器的负担,提升网站性能
- 加快了客户端加载网页的速度
缺点:
资源如果有更改但是客户端不及时更新会造成用户获取信息滞后
HTTP缓存有哪几种
根据加载缓存是否需要同服务器交互可以将缓存分为 强缓存 与 协商缓存
- 强缓存:浏览器直接从本地缓存中获取数据,不与服务器进行交互。
- 协商缓存:浏览器发送请求到服务器,服务器判定是否可使用本地缓存。
缓存流程图
与HTTP缓存有关的首部字段有哪些,有什么作用
与HTTP缓存有关的字段有:
首部字段名 | 说明 |
---|---|
Cache-Control | 控制对资源的缓存行为 |
Expires | 控制资源的过期时间 |
Last-Modified | 资源的最后修改日期时间 |
ETag | 资源的匹配信息 |
If-Non-Match | 条件式请求,服务器上没有任何资源的 ETag 属性值与这个首部中列出的相匹配的时候,服务器端会才返回所请求的资源,响应码为 200 。当验证失败的时候,服务器端必须返回响应码 304 |
If-Modified-Since | 条件式请求,服务器只在所请求的资源在给定的日期时间之后对内容进行过修改的情况下才会将资源返回,状态码为 200 。如果请求的资源从那时起未经修改,那么返回一个不带有消息主体的 304 响应。当与 If-None-Match 一同出现时,If-Modified-Since 会被忽略掉。 |
Cache-Control
代表了资源的缓存策略,常用的有以下几种选择:
Cache-Control字段 | 说明 |
---|---|
max-age | 表示缓存最大有效时间,以秒为单位 |
public | 表示可以被浏览器和代理服务器缓存 |
private | 客户端可以缓存该资源,但代理服务器不缓存 |
no-cache | 跳过设置强缓存,强制设置协商缓存 |
no-store | 不缓存,包括客户端、服务器都不缓存 |
immutable | 表示该资源永久不变(非标准) |
Expires
Expires 代表了资源的过期日期,在没有 Cache-Control 时,则会去查看是否包含 Expires 属性,通过比较 Expires 的值和首部里面 Date 属性的值来判断是否缓存还有效。
Last-Modified
如果没有 Cache-Control 和 Expires 时,Last-Modified 响应头可以作为一种弱校验器。浏览器隐式的设置资源过期时间为 (Date - Last-Modified) * 10% 缓存过期时间。如果响应头里含有这个信息,客户端可以在后续的请求中带上 If-Modified-Since 来验证缓存。
ETag
ETag 代表了资源的特定版本的标识符,用做缓存的一种强校验器。
- 浏览器请求资源,服务器会在响应报文头中加入 ETag 字段。资源更新时,服务器端的ETag值也随之更新;
- 浏览器再次请求资源时,会在请求报文头中添加 If-None-Match 字段,它的值就是上次响应报文中的 ETag 的值;
- 服务器会比对 ETag 与 If-None-Match 的值是否一致,如果不一致,服务器则接受请求,返回更新后的资源;如果一致,表明资源未更新,则返回状态码为 304 的响应,可继续使用本地缓存,要注意的是,此时响应头还是会加上 ETag 字段,即使它没有变化。
If-Non-Match If-Modified-Since
当一个资源被缓存存储后,该资源应该可以被永久存储在缓存中。由于缓存只有有限的空间用于存储资源副本,所以缓存会定期地将一些副本删除,这个过程叫做 缓存驱逐 。另一方面,当服务器上面的资源进行了更新,那么缓存中的对应资源也应该被更新,由于HTTP是C/S模式的协议,服务器更新一个资源时,不可能直接通知客户端更新缓存,所以双方必须为该资源约定一个过期时间,在该过期时间之前,该资源(缓存副本)就是新鲜的,当过了过期时间后,该资源(缓存副本)则变为陈旧的。驱逐算法用于将陈旧的资源(缓存副本)替换为新鲜的,注意,一个陈旧的资源(缓存副本)是不会直接被清除或忽略的,当客户端发起一个请求时,缓存检索到已有一个对应的陈旧资源(缓存副本),则缓存会先将此请求附加一个 If-None-Match 头,然后发给目标服务器,以此来检查该资源副本是否是依然还是算新鲜的,若服务器返回了 304 (Not Modified)(该响应不会有带有实体信息),则表示此资源副本是新鲜的,这样一来,可以节省一些带宽。若服务器通过 If-None-Match 或 If-Modified-Since 判断后发现已过期,那么会带有该资源的实体内容返回。