当前位置: 首页 > 科技观察

通过HTTP协议做网页缓存

时间:2023-03-22 16:44:25 科技观察

亲,你知道什么是缓存吗?其实缓存就像申请一张健身卡一样。第一次花699办了一年卡后,明年就可以免费健身了。在网络中,我们付出的不是金钱,而是空间。当我们消耗一定的空间后,我们在打开网页的速度上就能得到质的飞跃。当我们第一次访问一个页面时,需要支付一定的空间,将下载的css、js、html、img等相关资源保存到本地。第二次,第三次。..访问时,您不必下载文件。一般来说,有两种方式来设置文件的缓存。一种是在服务器中设置响应头文件,另一种是使用h5清单文件进行相关设置。我们先看看消息设置响应头的方式。Server这样设置的缓存有两种,一种需要服务器验证,一种不需要发送请求验证。ETag/Last-Modified两种方法类似,都是向服务器发送请求进行校验。简单的说,缓存就是缓存了,为什么还要校验呢?实际上,这是该协议的一种独特方法。发送验证主要是检查文件是否发生了变化。ETagETag用于计算文件内容是否发生变化。比如你删除了文件中的一个空格,就认为文件的内容发生了变化。通常的做法是使用md5或SHA1算法来计算文件的唯一值。其实可以在前端完成。找一个文件解析md5算法,然后把文件传进去,得到ETag的值。但是在这里,我们的重点不是让你生成Etag,而是看一下ETag在缓存中的重要作用。ETag是HTTP/1.1A的一种方法,由Web服务器生成,写入响应头中。//responseHeadersETag:"751F63A30AB5F98F855D1D90D217B356"然后,到达浏览器后缓存到本地。下次打开同一篇文章时,会在请求头中发送If-None-Match,检查文件是否已更改到服务器。如果没有,告诉浏览器使用本地的,否则返回一个新的文件//requestHeadersIf-None-Match:"751F63A30AB5F98F855D1D90D217B356"正常情况下,服务端默认开启Etag,但是为了防止同事或者后台配置后台brother文件不对,Etag被关闭了。这时候就需要对配置文件进行一些设置。这里我以Nginx为例:打开ngnix.conf文件,查看是否有如下语句:etagoff;more_set_headers-s404-t'ETag';more_clear_headers'Etag';如果有,请将其删除。然后重启nginx就可以了。他们关闭Etag的原因其实很简单。是因为开启Etag会增加服务器的负载,导致性能受限。因此,关闭或打开Etag必须权衡。Last-Modified这个不同于文档内容信息校验,这里是日期校验方式。即服务器会在文件上标记一个文件修改日期,然后客户端接受这个日期,在下次请求时返回日期,服务器进行验证。如果日期没有改变,就告诉浏览器使用本地缓存。即在服务器相应的header中,可以设置Last-Modified来开启这个缓存协议。//ResponseHeaderLast-Modified:Tue,03Mar201501:38:18GMT浏览器收到这个响应头后,会做A缓存,保存那个日期。下次请求时,会传入日期,通过If-Modified-Since验证:If-Modified-Since:Tue,03Mar201501:38:18GMT如果日期没有变化,就告诉浏览器使用缓存。那么我们平时应该如何开启服务器功能呢?默认情况下,服务器会向静态资源发送Last-modified标签。不过需要注意的是,Last-Modified的更新时间只能以秒来计算。如果你的文件变化太频繁,Last-Modified是无效的(不过,谁能在1秒内多次更新文件呢~)其实.Last-Modified标签通常不会单独使用。它通常与expires结合形成可降级缓存。Expires/Cache-ControlExpires/Cache协议与上述验证协议的区别在于,它可以省略发送验证请求的环节,不需要服务端的验证,直接使用本地缓存。通常这种方式适用于项目比较稳定,版本迭代不多的时候。Expires可以在服务器端设置Expires的绝对时间。//ResponseHeadersExpires:Tue,03May201609:33:34GMT这告诉浏览器在2016.5.3之前可以直接使用文本的缓存副本。但是,由于服务器端和客户端的GMT时间不同,可能会存在一定的bug。因此,只推荐在长期缓存的情况下使用。否则,您应该选择Cache-Control。那么如何在服务器端设置呢?这里以nginx为例:location~*\.(?:css|js)${expires1d;access_logoff;add_headerCache-Control"public";}passedexpires设置过期时间为一天。此时,服务器会在当前时间上加一天。同时添加Expires和Cache-Control标头标签。即得到的ResponseHeader为:Expires:Fri,28Feb201410:42:09GMTCache-Control:max-age=86400//24*60*60(HTTP规定如果出现max-age和expires,则max-age为默认覆盖Dropexpires)当expires为负数时表示无缓存,当为正数或零时表示max-age=time。如果不想缓存,可以直接设置:expires-1;//永远过期,Cache-Control:no-cacheCache-Control这个应该是HTTP1.1新增的,解决的时差bug在HTTP1.0标记中过期。它的配置项很多,实际上可以完全替代expires(现在大部分服务器都支持)。引用一句原话:HTTP/1.1规范中定义了Cache-Control头,取代了之前用来定义响应缓存策略的头(如Expires)。目前所有的浏览器都支持Cache-Control,所以用它就够了。不过目前大部分服务器都加上了,因为HTTP规定如果Cache-Control和expires同时出现,expires会默认被覆盖。此时返回的响应码不再是304(文件未更改),而是200(资源已成功访问)。在发送每个请求之前,浏览器会检查缓存系统中是否有对应文件的备份。如果是如果是,直接从本地理论知识上模仿一个Responseheader。让我们来看看。让我们来看看。查看cache-control有哪些可配置属性(以下属性跟在cache-control后面)public:共享缓存,可以使用Cache代理服务器缓存,比如CDNprivate:私有缓存,不能被publiccache代理服务器缓存,但是可以被用户的代理缓存,例如浏览器。max-age=[seconds]:表示缓存是新鲜的,在这个时间范围内不需要更新。类似于Expires时间,但是这个时间是相对的,不是绝对的。也就是说,在成功请求后多少秒缓存是新鲜的。s-maxage=[seconds]:与max-age类似,但仅适用于共享缓存(如代理)。no-cache:这里不是说不缓存,而是每次在使用缓存之前,强制向源服务器发送请求进行校验,检查文件应该没有变化(其实也没有太大的变化)不同于这里的ETag/Last)no-store:禁止缓存,不要让浏览器保留缓存的副本must-revalidate:告诉浏览器必须重新验证,检查信息是否过期,返回码为不是200而是304。proxy-revalidate:类似于must-revalidate,只是它只能应用于代理缓存。例如,这里我可以将Cache-Control设置为//ResponseHeadersCache-Control:private,max-age=0,must-revalidate。这个文件是私有文件,只能被浏览器缓存,不能被代理缓存。max-age表示缓存立即过期。其实和no-cache没有太大区别。然后must-revalidate告诉浏览器你必须再次验证文件是否已经过期。比如你接下来可能会验证Last-Modified或ETag。如果还没有过期,就使用本地缓存。其实上面可以直接等价于//ResponseHeadersCache-Control:private,no-cacheusingno-store//ResponseHeadersCache-Control:no-store;的结果这说明不管有什么不同都需要重新下载。强烈声明不允许您使用缓存文件。后续不会进行ETag的验证。当然,如果你考虑到IE6这样的老浏览器,那你就不要脸了,直接用下面的标签:Cache-Control:no-cache,no-store,must-revalidate//HTTP1.1Pragma:no-cache//HTTP1.0Expires:0//Proxy但是现在基本没有不支持Cache-Control的浏览器了。因此,一般情况下,可以直接使用如下策略进行设置:(来自googledeveloper)我们通常如何在nginx中配置相应的cache-controlheader?##Setno-cache//Nginxexpires-1;//cache-controlCache-Control:no-cache##设置max-age=0//Nginxexpires0;//cache-controlCache-Control:max-age=0##设置其他headers//nginxadd_headerCache-Control"no-cache";add_headerPragmano-cache;以上基本上就是服务器的响应头,那么在浏览器的Request头中有cache-control是什么意思呢?当请求头中有:Cache-Control:max-age=0时,表示需要缓存Validation(ETag||Last-Modified),如果缓存没有过期就可以使用。当请求头中有:Cache-Control:no-cache时,表示浏览器只能获取***文件。对应于ResponseHeader中的no-store。组合装箱方式的缓存策略上面介绍的last/ETag/Expires/Cache都是HTTP协议的缓存策略。当然,缓存不止一种。例如HTML4.0中定义的一些meta也可以实现自定义缓存="no-cache"/>但是实际情况是这些metas只能在本地存放在file://文件中使用,如果是服务器,默认情况下它将被覆盖。现在主流是使用HTTP1.1协议缓存,但是我们一般不会单独使用某一项。但是它们结合起来后的效果如何呢?如果您的网页不是特别定制的(私有的),使用缓存可以大大提高您网站的性能。所以推荐使用。一个网站,说白了就是HTML+JS+CSS+fonts+img这几类文件(视频就是呵呵)。我们可以为这些类型的文件做一些缓存级别。以上只是一个简单的设置。您必须知道HTML一定不能缓存(大多数网页)。缓存设置时间应该在你的版本稳定后设置,否则得不偿失。另外Cache-Control的设置也可以配合ETag或者Last-Modified进行补偿校验,如果后面文件有变化,也可以及时反映出来。清除缓存最常见的方法是修改文件的版本号,或者生成一个随机文件名。如果你只是在本地测试,想手动清除缓存,可以使用它。但是在Mac中就不一样了,使用command+R=F5刷新,command+shift+R=ctrl+F5硬reload。另外,即使你设置了Cachingstrategy,他也不会缓存文件。这些文件包括动态认证的文件,比如需要cookie验证的文件,输入验证码等。无法缓存POST请求文件。