前言
http协议的缓存机制可以大大减轻客户端向服务器发送的请求次数,从而减少服务器的负载压力;与此同时,缓存机制的存在也可以提升响应速度,减少等待时间。
HTTP报文作为浏览器和服务器间通信时发送及响应的数据报文,其请求和响应报文中通常都包含着跟缓存相关的信息。HTTP报文通常分为两部分:报文首部和body,而与缓存相关的信息主要存在于报文首部中。
http协议缓存常见的首部
httpd协议中的缓存首部出现在请求报文和响应报文的意义,不尽相同。通常请求报文的缓存首部意味着客户端通知服务器,客户端本地将会对缓存作出何种处理或与服务器作缓存比较。而响应报文中的缓存首部,则是服务器通知客户端对缓存的处理应遵循何种规则。下面我们来看一下在http协议中常见的与缓存相关的首部。
1、Expires
Expires是HTTP 1.0所提供的控制字段,是web服务器响应报文的字段,用于告诉客户端浏览器在Expires所指定的过期时间到来前,浏览器可直接从浏览器本地缓存中读取缓存响应请求,无需再次发送请求到服务器。
如图上述图中,Data表示请求报文发送的时间,而Expires则表示缓存在此日期到来前都是有效的。因此客户再次访问这类资源时,浏览器会直接从本地缓存中响应。
2、Cache-control
Cache-Control和Expires的作用差不多,都是用于指明当前资源的缓存有效期。通知客户端浏览器是从本地缓存中直接读取数据还是说重新发送请求到服务器中获取数据。Cache-control提供了多种资源有效期的选择,其优先级高于Expires。下面我们来一起看下Cache-control可使用的值。
prublic:用于指示客户端请求的资源科被任何缓存区所缓存。
private:用于指示对于当前某个用户的全部或部分响应信息,不能被共享缓存区所缓存处理。
no-cache:指示说明当前带请求或响应的消息不能被缓存。
no-store:用于防止重要的信息被无意的发布,在请求消息中附带此Cache-control值将使得请求和响应消息都不能使用缓存。
max-age:在响应报文中max-age通常用于告知客户端当前请求资源的缓存有效期的最大值(以秒为单位);而在请求报文中通常使用max-age=0,表示客户端向服务器发送请求确认,确认当前请求的资源是否有修改,如果没有则直接使用本地缓存,否则从服务器中获取请求资源。
min-fresh:要求缓存服务器返回至少还未过指定时间的缓存资源。
max-stale:该指令表示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
3、Last-Modified/If-Modified-Since
Last-Modified/If-Modified-Since需要配置Cache-control一起使用。
Last-Modified:web服务器在响应请求时,会使用此字段来告诉浏览器,其请求的资源的最后修改时间。
If-Modified-Since:当资源过期时或者请求中带有Cache-Control:max-age=0
,并且发现该资源的缓存具有Last-Modified声明,则向web服务器发送请求时带上If-Modified-Since。web服务器收到请求后,将比较If-Modified-Since与被请求资源的最后修改时间。如果最后修改时间比If-Modified-Since的值更新,说明资源已经被改动过,服务器会响应此请求的资源,响应状态码为200;否则,说明资源没更新,则响应HTTP 304,告知浏览器可继续使用本地缓存。
4、Etag/If-None-Match
Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。
Etag 可以解决 Last-Modified 无法解决的一些问题。
1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的变化时秒为单位的,这种修改无法判断。因此需要Etag来判断。
3、某些服务器不能精确的得到文件的最后修改时间;
如果Last-Modified与ETag一起使用时,服务器会优先验证ETag。而Last-Modified的优先级又高于Expires
也就是优先级:ETag>Last-Modified>Expires
If-None-Match:当资源过期时或者请求报文带有Cache-Control:max-age=0
时,并且发现该资源的缓存具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。
5、示例
从上述两张截图可看出,第一次web请求响应因为是服务器直接响应的,因此状态码为200。因为第一次请求的响应报文中带有ETag和Last-Modified字段,而且第二次的请求报文中的带有Cache-Contron:max-age=0,因此If-None-Match和If-Modified-Since也自然而然地被添加到了请求报文当中,用于与服务器确认请求的资源是否被修改过。
http协议缓存工作原理
当浏览器第一次发送http请求时,本地通常来说是没有缓存的,因此浏览器需要发送请求到服务器上去获取响应资源。此时浏览器向服务器发送的请求报文中通常会包含Cache-Control来告知服务器本地将对缓存作出何种处理。而服务器收到请求后,会将相关的缓存信息(Etag、Last-Modified等等)连通请求资源一起响应客户端。后续客户端的再次访问的请求报文,将结合缓存资源中的相关缓存字段来做出判断,最后决定使用本地缓存还是服务器再次响应该请求。
参考链接:https://blog.csdn.net/moshenglv/article/details/52020563
https://blog.csdn.net/rui0838/article/details/52727343
http://www.cnblogs.com/Leo_wl/p/5686610.html?utm_source=itdadao&utm_medium=referral