http协议缓存详解

在web应用中,缓存无处不在,浏览器有浏览器缓存,代理服务器有缓存,服务器有服务器缓存,php有缓存,数据库有缓存等等……本文主要讲解http协议中的缓存。

http缓存的是指:当Web请求抵达缓存时, 如果本地有“已缓存的”副本,就可以从本地存储设备而不是从原始服务器中提取这个文档。

缓存的好处:

缓存的好处是显而易见的,主要如下:
  1. 减少冗余数据传输,节省带宽
  2. 减少服务器负担,提高服务器性能
  3. 加快客户端加载网页的速度。

使用chrome(谷歌浏览器)查看http请求头中缓存信息:

通过chrome的开发者工具,可以看到http协议完整的请求头,如下图:
17785424[4]
对于静态请求,一般都会缓存,如上图,返回的就是“304 Not Modified”。

如何判断缓存是否需要更新:

主要有如下几种方式:

Expires策略

Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。如下图:

18513418[4]

Cache-control策略

Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。

Cache-control头部如下:

值可以是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age
各个消息中的指令含义如下:
  • Public指示响应可被任何缓存区缓存。
  • Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
  • no-cache指示请求或响应消息不能缓存
  • no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
  • max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应
  • min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
  • max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

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。 如下两图:
如果文档没有更新:
19675314[4]

如果文档有更新:

19791410[4]

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。

Etag的出现主要是为了解决几个比较难解决的问题:

Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

与缓存相关的http请求头(header):

Request

Cache-Control: max-age=0 以秒为单位
If-Modified-Since:Wed, 27 Nov 2013 16:02:46 GMT 缓存文件的最后修改时间。
If-None-Match: "0693f67a67cc1:0" 缓存文件的Etag值
Cache-Control: no-cache 不使用缓存
Pragma: no-cache 不使用缓存

 

 

   

 

 

Response

Cache-Control: public 响应被缓存,并且在多用户间共享
Cache-Control: private 响应只能作为私有缓存,不能在用户之间共享
Cache-Control:no-cache 提醒浏览器要从服务器提取文档进行验证
Cache-Control:no-store 绝对禁止缓存(用于机密,敏感文件)
Cache-Control: max-age=60 60秒之后缓存过期(相对时间)
Date: Wed, 27 Nov 2013 16:02:46 GMT 当前response发送的时间
Expires: Wed, 27 Nov 2013 18:00:00 GMT 缓存过期的时间(绝对时间)
Last-Modified: Wed, 27 Nov 2013 12:02:46 GMT 服务器端文件的最后修改时间
ETag: "20b1add7ec1cd1:0" 服务器端文件的Etag值

如果同时存在cache-control和Expires怎么办呢?
浏览器总是优先使用cache-control,如果没有cache-control才考虑Expires 

浏览器缓存的几个区别:

在浏览器上点击刷新按钮、按Ctrl+F5刷新和输入网址后按回车键,使用的是不同的缓存机制,具体如下:
  • 按刷新按钮:需要到服务器检查页面对象是否过期,不过期则使用缓存;
  • 按Ctrl+F5:强制刷新,不使用缓存,请求头中会有no-cache标签;
  • 输入网址后按回车:如果本地缓存存在并未过期,则直接使用而无需请求服务器。

猜你喜欢

转载自blog.csdn.net/laiyuan999/article/details/80011618