HTTP缓存

本文详细解释了HTTP缓存的工作原理,包括强制缓存、协商缓存的区别,以及私有缓存和共享缓存的概念。还介绍了如何通过Cache-Control、Expires、Last-Modified和ETag进行缓存校验。此外,还提到了在SpringbootWeb和Nginx配置中实现静态资源缓存的方法。
摘要由CSDN通过智能技术生成

参考资料:

https://juejin.cn/post/7087759660391858183

https://juejin.cn/post/6844903816664449031

https://www.jianshu.com/p/227cee9c8d15

HTTP缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。当 HTTP 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的副本,而不会去源服务器重新下载。

使用HTTP缓存的好处主要有以下几点

  • 减少了冗余的数据传输,节省了网费;
  • 缓解了服务器的压力, 大大提高了网站的性能;
  • 加快了客户端加载网页的速度。

可以被客户端缓存的HTTP 响应

  • 默认情况下,请求方法如 GET、HEAD的响应内容是可缓存的,在包含新鲜度信息的情况下,POST的响应内容也可以被缓存;
  • 默认情况下,响应码如 200、206、300、301、302、404 等的响应内容可以被缓存;
  • 响应头和请求头没有指明不使用缓存,如 Cache-Control: no-store。

http缓存的分类

根据是否需要重新向服务器发起请求来分类,可分为:强制缓存、协商缓存。

根据是否可以被单个或者多个用户使用来分类,可分为:私有缓存、共享缓存 。

强制缓存和协商缓存

强制缓存如果生效,不需要再和服务器发生交互,而协商缓存不管是否生效,都需要与服务端发生交互。

强制缓存

强制缓存在缓存数据未失效的情况下(即Cache-Control的max-age没有过期或者Expires的缓存时间没有过期),那么就会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。强制缓存生效时,http状态码为200。这种方式页面的加载速度是最快的,性能也是很好的,但是在这期间,如果服务器端的资源修改了,页面上是拿不到的,因为它不会再向服务器发请求了。这种情况就是我们在开发种经常遇到的,比如你修改了页面上的某个样式,在页面上刷新了但没有生效,因为走的是强缓存。

注意:
Pragma和Cache-control共存时,Pragma的优先级是比Cache-Control高。

协商缓存

当第一次请求时服务器返回的响应头中没有Cache-Control和Expires或者Cache-Control和Expires过期还或者它的属性设置为no-cache时(即不走强缓存),那么浏览器第二次请求时就会与服务器进行协商,与服务器端对比判断资源是否进行了修改更新。如果服务器端的资源没有修改,那么就会返回304状态码,告诉浏览器可以使用缓存中的数据,这样就减少了服务器的数据传输压力。如果数据有更新就会返回200状态码,服务器就会返回更新后的资源并且将缓存信息一起返回。

跟协商缓存相关的header头属性有(ETag/If-Not-Match 、Last-Modified/If-Modified-Since)请求头和响应头需要成对出现。

协商缓存的执行流程:当浏览器第一次向服务器发送请求时,会在响应头中返回协商缓存的头属性:ETag和Last-Modified,其中ETag返回的是一个hash值,Last-Modified返回的是GMT格式的最后修改时间。然后浏览器在第二次发送请求的时候,会在请求头中带上与ETag对应的If-Not-Match,其值就是响应头中返回的ETag的值,Last-Modified对应的If-Modified-Since。服务器在接收到这两个参数后会做比较,如果返回的是304状态码,则说明请求的资源没有修改,浏览器可以直接在缓存中取数据,否则,服务器会直接返回数据。

注意:
ETag/If-Not-Match是在HTTP/1.1出现的,主要是解决以下问题:

(1)、Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间

(2)、如果某些文件被修改了,但是内容并没有任何变化,而Last-Modified却改变了,导致文件没法使用缓存

(3)、有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形

私有缓存和共享缓存

私有缓存

仅供一个客户端使用的缓存,即客户端上的缓存仅供自己使用,通常只存在于如浏览器这样的客户端上。

每个客户端发起的第一个请求都会被源服务器处理。在缓存生效的情况下,同一个客户端后续的相同请求甚至不会被发送,而是由本地缓存提供服务。

注:通过 Cache-Control: Private 控制。

共享缓存

可以供多个客户端使用的缓存,通常依赖于代理服务器。

客户端发起的第一个请求通过代理服务器访问源服务器,缓存生效后会存放在代理服务器,后续客户端发起的相同请求,均由代理服务器提供缓存服务,共享缓存可以减轻源服务器的压力。

注:通过 Cache-Control: Public 控制。

缓存控制策略:Cache-Control

对于网站来说,缓存是达到高性能的重要组成部分,缓存需要合理配置,因为并不是所有资源都是永久不变的。Cache-Control 首部可以对缓存进行控制,Cache-Control 能用于 HTTP 请求和响应中,支持多个指令,以逗号分隔。需要注意的是当有多个值时,是有优先级的,no-store优先级最高。

请求首部描述
Cache-Control: no-store 不使用缓存。
Cache-Control: no-cache使用缓存前,无论本地副本是否过期,都需要请求源服务器进行验证(协商缓存验证)。
Cache-Control: max-age=秒设置缓存存储的最大期限,超过这个期限缓存被认为过期,时间是相对于请求的时间。
Cache-Control: max-stale=秒客户端愿意接收一个已经过期的资源。可以设置一个可选的秒数,表示响应不能已经过时超过该给定的时间。
Cache-Control: min-fresh=秒 客户端希望获取一个能在指定的秒数内保持其最新状态的响应。
响应首部 描述
Cache-Control: no-store 不使用缓存。
Cache-Control: no-cache使用缓存前,无论本地副本是否过期,都需要请求源服务器进行验证(协商缓存验证)。
Cache-Control: max-age=秒设置缓存存储的最大期限,超过这个期限缓存被认为过期,时间是相对于请求的时间。
Cache-Control: s-maxage=秒  同 max-age,仅适用于共享缓存。
Cache-Control: private私有缓存,响应只能被单个客户端缓存。
Cache-Control: public共享缓存,即由缓存代理服务器提供的缓存,响应可以被多个客户端缓存。
Cache-Control: must-revalidate如果本地副本未过期,则可继续供客户端使用,不需要向源服务器再验证;如果本地副本已过期(比如已经超过max-age),在成功向源服务器验证之前,缓存不能用该资源响应后续请求。
Cache-Control: proxy-revalidate 同 must-revalidate,仅适用于共享缓存。

Expires(缓存校验)

服务器设置Expires字段为一个日期,客户端请求该资源时将这个日期与客户端当前日期进行比对,如果当前时间小于这个日期,则表示资源未过期,使用缓存,如果当前时间大于这个日期,则表示资源已过期,客户端就会重新请求该资源.但是这一策略会收到客户端与服务器时间不一致的问题的影响.如果客户端时间晚于服务器的时间,会导致资源还未过期就重新请求,反之,会导致客户端还在使用过期的旧资源.

Last-Modified / If-Modified-Since(缓存校验)

当浏览器第一次请求一个资源时,服务端返回状态码200,返回请求的资源的同时HTTP响应头会有一个Last-Modified标记着文件在服务端最后被修改的时间。
浏览器第二次请求上次请求过的资源时,浏览器会在HTTP请求头中添加一个If-Modified-Since的标记,用来询问服务器该时间之后文件是否被修改过。


如果服务器端的资源没有变化,则自动返回304状态,使用浏览器缓存,从而保证了浏览器不会重复从服务器端获取资源,也保证了服务器有变化时,客户端能够及时得到最新的资源。

Etag / If-None-Match(缓存校验)

当浏览器第一次请求一个资源时,服务端返回的状态码为200,同时HTTP相应头会有一个Etag字段,存放着服务器端生成的一个序列值。


浏览器第二次请求上次请求过的url时,浏览器会在HTTP请求头添加一个If-None-Match的标记,用来询问服务器该文件有没有被修改。


如果服务器的资源没有变化,Etag字段没有被修改依然与If-None-Match的值保持一致,则请求自动返回304状态,使用浏览器缓存。如果不一致,则说明资源被更改,则重新去下载新的资源。

如何使用HTTP缓存 

html页面缓存的设置主要是在<head>标签中嵌入<meta>标签;

1、html页面禁用缓存的设置如下
<meta http-equiv="pragma" content="no-cache">
// 仅有IE浏览器才识别的标签,不一定会在请求字段加上Pragma,但的确会让当前页面每次都发新请求
<meta http-equiv="cache-control" content="no-cache">
// 其他主流浏览器识别的标签
<meta http-equiv="expires" content="0">
// 仅有IE浏览器才识别的标签,该方式仅仅作为知会IE缓存时间的标记,你并不能在请求或响应报文中找到Expires字段

2、html设置缓存如下
<meta http-equiv="Cache-Control" content="max-age=7200" />
// 其他主流浏览器识别的标签
<meta http-equiv="Expires" content="Mon, 20 Aug 2018 23:00:00 GMT" />
// 仅有IE浏览器才识别的标签

修改web服务器上的配置,如nginx配置文件

具体操作步骤见:https://www.cnblogs.com/bdhk/p/9198499.html

Spring boot Web 实现静态资源缓存

具体操作步骤见:https://blog.csdn.net/m0_37845840/article/details/81382462

  • 32
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值