|
点击蓝字关注我们01HTTP协议是什么?1.1概念简介HTTP协议是Hyper Text Transfer rotocol(超文本传输协议)的缩写,是用于从万维网(WWW:WorldWideWeb)服务器传输超文本到本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议来传递数据(HTML文件,文件,查询结果等)。HTTP协议工作于客户端-服务端架构之上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。图1.1.1HTTP的Client-Server模型1.2HTTP协议的发展史最初的HTTP0.9极其简单,请求由单行指令构成;到HTTP2.0时则拥有更优异的表现,更多的数据通过HTTP请求被传输,由此HTTP2.0为网络效率做了大量的优化。HTTP3.0目前处于制订和测试阶段,是未来的全新的HTTP协议,HTTP3.0协议运行在QUIC协议之上,是在UDP的基础上实现了可靠传输,使用UDP将避免TCP的队头阻塞问题,并加快网络传输速度,但同样需要实现可靠传输的机制,HTTP13.0不是HTTP12.0的拓展,HTTP3.0将会是一个全新的协议。1.3协议工作HTTP请求由请求行、消息报头、请求正文三部分组成。今天我们要介绍的缓存机制,就跟消息报头有很大关系,它决定了浏览器的缓存行为。通过浏览器的「检查」功能(F12),我们可以很方便地查看HTTP协议的传输过程:图1.3.1查看网络传输内容及使用的协议(图中为http协议)随意点开其中一个css文件的传输详情,查看http传输过程中的细节:图1.3.1查看请求包头可以看到,请求包头其实是由键值对(keyvalue)的形式组成,每个头部对应了不同的行为及含义。02为什么需要有缓存?上面我们说到,HTTP协议是一个Client-Server的工作模型,那么也就说明,所有浏览器浏览的内容和资源,都是从服务器上下载下来的。●1如果每次刷新浏览网页,我们都需要从服务(Server)端获取资源文件,如果资源文件又特别大,就会导致请求时间被拉的很长,上网冲浪体验极差!●1同时,如果所有的大文件资源都需要到Server端去获取,也会导致服务器压力增大,带宽成本变高为了解决这个问题,浏览器引入了资源缓存机制——浏览器在请求资源时,会与服务器进行协商,能缓存的静态资源则会缓存到浏览器本地,供下次访问使用。图2.1.1浏览器缓存协商图2.1.2浏览器的缓存资源03缓存控制机制原理介绍3.1根据什么规则缓存1. 新鲜度(过期机制):也就是缓存副本有效期。一个缓存副本必须满足以下条件,浏览器会认为它是有效的,足够新的:●1含有完整的过期时间控制头信息(HTTP协议报头),并且仍在有效期内;●1浏览器已经使用过这个缓存副本,并且在一个会话中已经检查过新鲜度;2. 校验值(验证机制):服务器返回资源的时候有时在控制头信息带上这个资源的实体标签(如Etag),它可以用来作为浏览器再次请求过程的校验标识。如果发现校验标识不匹配,说明资源已经被修改或过期,浏览器需求重新获取资源内容。3. 辅助:Vary头。用于区分不同副本的缓存,比如:当『请求头」中带有Vary:Accept-Encoding,浏览器可以根据「响应头」中不同的Content-Encoding,来缓存不同的内容副本;3.2HTTP缓存的两个阶段浏览器缓存一般分为两类:强缓存(也称本地缓存)和协商缓存(也称弱缓存)。本地缓存阶段浏览器发送请求前,会先去缓存里查看是否命中强缓存,如果命中,则直接从缓存中读取资源,不会发送请求到服务器。否则,进入下一步。协商缓存阶段当强缓存没有命中时,浏览器一定会向服务器发起请求。服务器会根据RequestHeader中的一些字段来判断是否命中协商缓存。如果命中,服务器会返回304响应,但是不会携带任何响应实体,只是告诉浏览器可以直接从浏览器缓存中获取这个资源。如果本地缓存和协商缓存都没有命中,则从直接从服务器加载资源。图3.2.1HTTP缓存的两个阶段下面是缓存处理的一个过程:图3.2.2缓存处理流程3.3新鲜度上面说到,新鲜度其实就是指的缓存副本的有效时间。那么浏览器究竟是通过怎么样的机制来指定新鲜度的呢?理论上来讲,当一个资源被缓存存储后,该资源应该可以被永久存储在缓存中。由于缓存只有有限的空间用于存储资源副本,所以缓存会定期地将一些副本删除,这个过程叫做缓存驱逐。另一方面,当服务器上面的资源进行了更新,那么缓存中的对应资源也应该被更新,由于HTTP是C/S模式的协议,服务器更新一个资源时,不可能直接通知客户端更新缓存,所以双方必须为该资源约定一个过期时间,在该过期时间之前,该资源(缓存副本)就是新鲜的,当过了过期时间后,该资源(缓存副本)则变为陈旧的。驱逐算法用于将陈旧的资源(缓存副本)替换为新鲜的,注意,一个陈旧的资源(缓存副本)是不会直接被清除或忽略的,当客户端发起一个请求时,缓存检索到已有一个对应的陈旧资源(缓存副本),则缓存会先将此请求附加一个If-None-Match头,然后发给目标服务器,以此来检查该资源副本是否是依然还是算新鲜的,若服务器返回了304(NotModified)(该响应不会有带有实体信息),则表示此资源副本是新鲜的,这样一来,可以节省一些带宽。若服务器通过If-None-Match或If-Modified-Since判断后发现已过期,那么会带有该资源的实体内容返回。在HTTP协议中,控制缓存新鲜度的Header常见有这些3.3.1Expires(HTTP/1.0)Expires是HTTP1.0版本引入的缓存时间控制头部,意味着在多长的时间内缓存内容将过期。Expires响应头包含日期/时间,即在此之后,响应过期。无效的日期,比如0,代表着过去的日期,即该资源已经过期。如果在Cache-Control响应头设置了"max-age"或者 "s-max-age"指令,那么Expires头会被忽略。语法:Expires:3.3.2Pragma(HTTP/1.0)Pragma是HTTP1.0版本引入的通用头部,主要用于制定内容是否为不缓存。其效果类似Cache-Control:no-cache。它用来向后兼容只支持HTTP1.0协议的Server,那时候HTTP1.1中的Cache-Control还没有出来。语法:Pragma:no-cache3.3.3Cache-Control(HTTP/1.1)Cache-Control是HTTP1.1版本引入的头部,被用于在http请求和响应中,通过指定指令来实现缓存机制。Cache-Control头在缓存控制方面发挥着巨大且重要的作用,是目前主流浏览器用于控制缓存的重要头部。在【请求】中可以使用的一些Cache-Control指令:在【响应】中可以使用的一些Cache-Control指令:我们可以将Cache-Control的控制指令,分为可缓存性、到期、其他三类。可缓存性:public表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存,即使是通常不可缓存的内容。(例如:1.该响应没有max-age指令或Expires消息头;2.该响应对应的请求方法是POST。)private表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。私有缓存可以缓存响应内容,比如:对应用户的本地浏览器。no-cache在发布缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证(协商缓存验证)。no-store缓存不应存储有关客户端请求或服务器响应的任何内容,即不使用任何缓存。_________________________到期:max-age=设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间。s-maxage=覆盖max-age或者Expires头,但是仅适用于共享缓存(比如各个代理),私有缓存会忽略它。max-stale[=]表明客户端愿意接收一个已经过期的资源。可以设置一个可选的秒数,表示响应不能已经过时超过该给定的时间。min-fresh=表示客户端希望获取一个能在指定的秒数内保持其最新状态的响应。stale-while-revalidate=表明客户端愿意接受陈旧的响应,同时在后台异步检查新的响应。秒值指示客户愿意接受陈旧响应的时间长度。stale-if-error=表示如果新的检查失败,则客户愿意接受陈旧的响应。秒数值表示客户在初始到期后愿意接受陈旧响应的时间。重新验证和重新加载must-revalidate一旦资源过期(比如已经超过max-age),在成功向原始服务器验证之前,缓存不能用该资源响应后续请求。proxy-revalidate与must-revalidate作用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。immutable表示响应正文不会随时间而改变。资源(如果未过期)在服务器上不发生改变,因此客户端不应发送重新验证请求头(例如If-None-Match或If-Modified-Since)来检查更新,即使用户显式地刷新页面。在Firefox中,immutable只能被用在https://transactions.有关更多信息,请参阅这里。_________________________其他no-transform不得对资源进行转换或转变。Content-Encoding、Content-Range、Content-Type等HTTP头不能由代理修改。例如,非透明代理或者如Google'sLightMode可能对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。no-transform指令不允许这样做。only-if-cached表明客户端只接受已缓存的响应,并且不要向原始服务器检查是否有更新的拷贝。3.4校验值(验证机制)首先,缓存验证是什么东西?当一个缓存内容,本地浏览器不知道它是否过期,且需要验证时,客户端(浏览器)会发起一个请求,携带上特定的缓存验证头部回到服务器;若服务器校验后认为内容没有更新,则吐出HTTP状态码304,告诉客户端内容没有更新,这时候客户端可以继续使用本地的缓存进行服务。当缓存的内容过期后,需要进行缓存验证或者重新获取资源。只有在服务器返回强校验器或者弱校验器时才会进行验证。让我们看一个例子:在腾讯云CDN上添加一个加速域名,并配置好对应的解析;我们通过curl命令来模拟客户端的请求,获取CDN上的服务资源。第一次,我们先正常地获取内容资源:curl'lego.jwlchina.cn/hello.txt'-v服务器正常吐出了内容,并返回了200状态。这里我们注意到,Server还给我们返回了一个头部:ETag:"61becfea-d" 如果我们按照HTTP1.1协议中的定义,在下一次请求中带上If-None-Match头,验证缓存内容的有效性,看看会发生什么。我们还是做一次curl请求模拟客户端,但这次我们会带上If-None-Match头,同时头部的值为上次Server吐给我们的ETag值:curl'lego.jwlchina.cn/hello.txt' -v-H"If-None-Match:\"61becfea-d\""我们可以看到,服务器返回了304,同时没有返回任何内容。这时候其实从客户端可以得知,我们缓存的内容没有任何更新,那就可以放心地继续使用之前缓存下来的内容了。可见,缓存验证与协商,也是缓存的重要一环,能为我们服务器节省许多的带宽开销。常见的缓存校验头部:3.4.1Last-Modified&If-Modified(HTTP/1.0)用于校验资源是否过期;Last-Modified与If-Modified-Since通常会被组合来使用,对应响应阶段以及请求阶段。在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,格式类似这样:Last-Modified:Wed,21Oct201507:28:00GMT客户端第二次请求此URL时,根据HTTP协议的规定,浏览器会向服务器传送If-Modified-Since报头,询问该时间之后文件是否有被修改过:If-Modified-Since:Wed,21Oct201507:28:00GMT如果服务器端的资源没有变化,则自动返回HTTP304(NotChanged.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。3.4.2ETag&If-None-Match(HTTP/1.1)HTTP协议规格说明定义ETag为“被请求变量的实体值”。另一种说法是,ETag是一个可以与Web资源关联的记号(token)。典型的Web资源可以一个Web页,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,以下是服务器端返回的格式:ETag:"50b1c1d4f775c61:df3"客户端的查询更新格式是这样的:If-None-Match:"50b1c1d4f775c61:df3"如果ETag没改变,则返回状态304然后不返回,这也和Last-Modified一样。3.5辅助3.5.1Vary对于服务器而言,资源文件可能不止一个版本,比如说压缩和未压缩,针对不同的客户端,通常需要返回不同的资源版本。比如说老式的浏览器可能不支持解压缩,这个时候,就需要返回一个未压缩的版本;对于新的浏览器,支持压缩,返回一个压缩的版本,有利于节省带宽,提升体验。那么怎么区分这个版本呢,这个时候就需要Vary了。服务器通过指定 Vary:Accept-Encoding,告知代理服务器,对于这个资源,需要缓存两个版本:压缩和未压缩。这样老式浏览器和新的浏览器,通过代理,就分别拿到了未压缩和压缩版本的资源,避免了都拿同一个资源的尴尬。Vary:Accept-Encoding,User-Agent如上设置,代理服务器(CDN)将针对是否压缩和浏览器类型两个维度去缓存资源。如此一来,同一个url,就能针对PC和Mobile返回不同的缓存内容。04应用以腾讯云CDN为例,我们可以在CDN控制台上配置不同的缓存策略。4.1让浏览器将内容固定缓存10分钟在控制台上,为域名配置【浏览器缓存】图4.1.1CDN控制台上配置浏览器缓存时间图4.1.2实测配置浏览器缓存后的响应头部响应中头部包含了Cache-Control:max-age=600,浏览器则会按照响应中的头部,将内容缓存10分钟。4.2让CDN遵循源站的缓存控制图4.2.1在CDN控制台上配置缓存遵循源站让CDN缓存服务器遵循源站的缓存控制行为。若源站对应的HTTPResponseHeader中存在Cache-Control字段,则:●1若Cache-Control字段为max-age,CDN节点缓存资源的时间按照max-age值。●1若Cache-Control字段为no-cache/no-store/private,CDN节点不缓存资源。●1若源站对应的HTTPResponseHeader中无Cache-Control字段,则:CDN节点不缓存资源。05结语HTTP协议中的缓存控制机制,是我们学习HTTP协议的重点内容,了解清楚其背后的原理,对我们理解浏览器的缓存控制机制有很大的帮助。同时CDN是互联网缓存服务器的重要参与者,学习HTTP协议的缓存机制,也能帮助我们理解CDN背后的一些缓存控制机制以及原理。共勉。summer扫码关注收获更多~我知道你在看哟
|
|