likes
comments
collection
share

图解HTTP缓存

作者站长头像
站长
· 阅读数 28

HTTP缓存是一种用于存储Web资源副本的机制。当浏览器向服务器请求某个资源时,服务器会返回该资源以及相关的缓存控制信息。如果浏览器发现缓存中有该资源的有效副本,就可以直接使用,而无需再次向服务器发送请求。这样可以减少网络流量,提高加载速度,并降低服务器的处理压力。

为了方便描述,本文所提到的"浏览器"特指所有实现了HTTP缓存机制的客户端。

HTTP缓存大致可以分为两类:强缓存和协商缓存。强缓存是指当缓存数据未失效时,浏览器直接使用浏览器缓存数据(从硬盘或者内存中取,由各浏览器的缓存实现机制决定),不向服务器发送任何请求。协商缓存是在浏览器检查发现强缓存命中失败或者当前请求声明了要暂时忽略本地缓存副本时,通过向服务器发送一个带有条件性的请求,让服务器端检查下资源是否真的有修改来决定是否使用本地缓存。

图解HTTP缓存

强缓存

强缓存判断数据有没有失效是通常通过HTTP响应头里面的Cache-Control或者Expires字段来控制,Cache-Control的优先级高于Expires。

HTTP/1.1 200 OK  
Content-Type: text/html; charset=UTF-8  
Content-Length: 12345  
Last-Modified: Mon, 21 Oct 2023 20:13:21 GMT  
Cache-Control: max-age=3600  
Expires: Tue, 22 Oct 2023 20:13:21 GMT  

Expires字段表示资源的过期时间,用一个GMT(格林威治标准时间)来表示。如果客户端在过期时间之前请求该资源,就会直接使用缓存中的资源,而不会向服务器发送请求。然而由于Expires依赖于客户端本地的时间,一旦客户端时间和服务器时间不一致有可能会导致缓存不可用。

Cache-Control字段是HTTP/1.1版本引入的,它包含一系列的指令,用于指示缓存的行为,最常用的还是max-age指令。max-age指令可以设置缓存的有效时间,代表的是相对于资源最后修改时间的秒差。在max-age设置的秒数内,如果客户端再次请求资源,就会直接从缓存中获取,而不会向服务器发送请求。

图解HTTP缓存

强缓存命中的情况下,客户端会直接取本地缓存中的信息,此时如果进入浏览器的开发者工具中查看这一条HTTP请求的情况,可以看到在"Status Code: 200 OK"的后面会有"from memory cache"或者"from disk cache"的标识。

强缓存是否命中,各个浏览器都有自己的一套实现机制,一般都会自己保存响应头中的Cache-Control和Expires字段数据。当再次发起请求的时候,客户端会依据Cache-Control或者Expires的值以及当前资源在浏览器端已经被缓存了的时间判断缓存是否过期。

协商缓存

协商缓存则是客户端在向服务器发送请求时,附带缓存资源的标识信息(如Last-Modified或ETag),服务器根据这些标识来判断资源是否发生过变化。如果资源未变化,则服务器返回304状态码,告知客户端可以继续使用缓存资源。

前面有说过,协商缓存是在强缓存命中失败或者当前HTTP请求声明了要忽略本地缓存副本时进行的。强缓存命中的判定在前面已经做过说明,这里就不再赘述了。

至于如何发起一个忽略本地缓存副本的请求,最常见的做法就是设置Cache-Control为no-cache。当Cache-Control被设置为no-cache时,浏览器会忽略其本地缓存的副本。

如果在请求上带一些条件性的请求字段,比如ETag或者是Last-Modified,服务端拿到这些请求的时候就会校验请求的资源是否被修改过。如果检查发现没有修改过,服务器就会返回一个 304 Not Modified 状态码,否则就会返回200状态码和更新后的资源信息。

浏览器端在发现服务端响应的状态吗是304的时候就会直接使用存储在本地缓存的资源,否则就会使用更新后的资源。

图解HTTP缓存

对比

由于强缓存在命中的时候不会向服务器端发送请求,他对服务端造成的负担是最小的。但同时他也存在一定的局限性,如果服务器上的资源已经更新,如果强缓存命中了,客户端可能无法及时获取到最新的资源。因此,在实际应用中,我们需要根据具体的业务需求和场景来制定合适的缓存策略。

转载自:https://juejin.cn/post/7362057701793333284
评论
请登录