HTTP 缓存机制及原理

HTTP缓存的好处

一个页面可能有几百几千个请求,如果服务器每次都需要去响应请求,那么会造成服务器压力过大,可能造成服务器卡顿瘫痪,降低用户使用体验。通过浏览器的缓存控制,对实时性要求不高的数据进行缓存,可以减少甚至不需要再次对服务器的请求就可以显示数据。 好处如下:

  • 减少延迟 — 因为所发出的网页请求是指向更接近客户端的缓存而不再是源服务器端,因此请求所花费时间更短,这让网站看上去反应更快。

  • 降低网络负荷 — 因为缓存文件可以重复使用,节省了不少的带宽.这也给用户省了不少流量

HTTP报文结构

1.请求报文:一般分为三部分:请求行、请求头和请求体,但是要注意请求头和请求体之间的空行也是HTTP请求规范内容。请求行分为三部分,方法、资源路径和协议版本。
请求报文结构

2.响应报文:也分为三部分:响应行、响应头和响应体,响应头和响应体直接的空行也是HTTP的规范。响应行也分为三部分,协议版本,状态码和状态码描述。
响应报文结构

HTTP请求及响应流程

  • 初次请求
    初次请求
  • 再次请求
    再次请求

控制浏览器缓存

HTTP协议定义了几个可以用来控制浏览器缓存关键字,它们是:Expires, Pragma: no-cache, Cache-Control , Last-Modified , ETag。

1. Expires:+过期时间
Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。不过Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大(比如时钟不同步,或者跨时区),那么误差就很大,所以在HTTP 1.1版开始,被Cache-Control: max-age=秒替代。
过期时间必须是HTTP格式的日期时间,其他的都会被解析成当前时间“之前”,缓存会马上过期,HTTP的日期时间必须是格林威治时间(GMT),而不是本地时间。举例:
Expires: Fri, 30 Oct 2009 14:19:41
2. Pragma: no-cache
为了兼容HTTP1.0,可以使用Pragma: no-cache头来告诉浏览器不要缓存内容.许多人相信设置一个 Pragma: no-cache HTTP 协议可以控制缓存是否开启。这其实不是完全正确的。HTTP 协议的详细说明中并没有设置任何有关Pragma的条例,相反,Pragma请求十分有争议。虽然一部分缓存会受到此参数的影响,但大多数一点作用也没有,请使用header头协议代替它!(作用有争议,最好不用)
3. Cache-control:
Cache-control直译成中文就是缓存控制,它的作用就是缓存控制,这个http头的值有几种。
1) max-age=[秒] — 执行缓存被认为是最新的最长时间。类似于过期时间,这个参数是基于请求时间的相对时间间隔,而不是绝对过期时间,[秒]是一个数字,单位是秒:从请求时间开始到过期时间之间的秒数。
2) s-maxage=[秒] — 类似于max-age属性,除了他应用于共享(如:代理服务器)缓存
3) public — 标记认证内容也可以被缓存,一般来说: 经过HTTP认证才能访问的内容,输出是自动不可以缓存的;
4) no-cache — 强制每次请求直接发送给源服务器,而不经过本地缓存版本的校验。这对于需要确认认证应用很有用(可以和public结合使用),或者严格要求使用最新数据的应用(不惜牺牲使用缓存的所有好处)。指示请求或响应消息不能缓存,该选项并不是说可以设置”不缓存“,容易望文生义~
5) no-store — 强制缓存在任何情况下都不要保留任何副本
6) must-revalidate — 告诉缓存必须遵循所有你给予副本的新鲜度的,HTTP允许缓存在某些特定情况下返回过期数据,指定了这个属性,你高速缓存,你希望严格的遵循你的规则。
7) proxy-revalidate — 和 must-revalidate类似,除了他只对缓存代理服务器起作用
举例:Cache-Control: max-age=3600, must-revalidate
4. Last-Modified/If-Modified-Since:Last-Modified/If-Modified-Since要配合Cache-Control使用。
Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。
If-Modified-Since:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间一致,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。

5. Etag/If-None-Match:Etag/If-None-Match也要配合Cache-Control使用。

Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。
If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。

ps:Etag与Last-Modified区别:
1. Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
2. Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag一起使用时,服务器会优先验证ETag。
yahoo的Yslow法则中则提示谨慎设置Etag:需要注意的是分布式系统里多台机器间文件的last-modified必须保持一致,以免负载均衡到不同机器导致比对失败,Yahoo建议分布式系统尽量关闭掉Etag(每台机器生成的etag都会不一样,因为除了 last-modified、inode 也很难保持一致)。

用户行为与缓存

浏览器缓存行为还有用户的行为有关。

HTML配置no-cache

HTML配置不属于HTTP协议 ,Web开发者可以在HTML页面的节点中加入标签,(只有部分浏览器支持;缓存代理服务器不会解析html内容,所以不支持)

No-cache配置

html表头如下

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
<!-- HTTP 1.1 -->  
<meta http-equiv="pragma" content="no-cache">  
<!-- HTTP 1.0 -->  
<meta http-equiv="cache-control" content="no-cache">  
<!-- Prevent caching at the proxy server -->  
<meta http-equiv="expires" content="0">  
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" />  

此篇文章大部分为同类文章的收集与整理。
refer:
http://www.cnblogs.com/520yang/articles/4807408.html
http://www.cnblogs.com/futan/archive/2013/04/21/cachehuancun.html
http://www.cnblogs.com/blogsme/p/3393039.html
http://blog.csdn.net/anialy/article/details/38751555

猜你喜欢

转载自blog.csdn.net/wyg1230/article/details/78452383