http缓存

http缓存

在文档过期后(即客户端不认为该副本有效)。 客户端必须从服务器请求一份新的副本进行缓存。
不过如果服务端该文档并没有改变,那么重复请求无疑带来了额外的资源开销,http提供一种有效性验证,
若服务器发生更新,则客户端获取新的文件进行缓存,即利用有条件请求,要求验证对应的版本号。

新鲜度
服务器应当告知客户端能够将内容缓存多长时间,在这个时间之内就是新鲜的。
服务器可以用这两个首部之一来提供这种信息: Expires(过期)和 Cache-Control(缓存控制)

Expires首部规定文档“过期”的具体时间—此后就不应当认为它还是最新的。
Expires首部的语法如下:
Expires: date
例如:
Expires: Sun Mar 18 23: 59: 59 GMT 2001

客户端和服务器为了能正确使用 Expires首部,它们的时钟必须同步。这并不总是
很容易的,因为它们可能都没有运行像 Network Time Protoco(网络时间协议,NTP)
这样的时钟同步协议。用相对时间来定义过期的机制会更有用。 Cache-Control
首部可以用秒数来规定文档最长使用期——从文档离开服务器之后算起的总计时间。
使用期不与时钟同步,因此可以给出更精确的结果。
实际上, Cache- Control首部功能很强大。服务器和客户端都可以用它来说明新鲜度,
并且除了使用期或过期时间之外,还有很多指令可用。
Cach- Control首部的一些指令:
no-cache 请求 在重新向服务器验证之前,不要返回文档的缓存副本
no-store 请求 不要返回文档的缓存副本。不要保存服务器的响应
max-age 请求 缓存中的文档不能超过指定的使用期
max-stale 请求 文档允许过期(根据服务器提供的过期信息计算),但不能超过指令中指定的过期值
in-fresh 请求 文档的使用期不能小于这个指定的时间与它的当前存活时间之和。换句话说,响应必须至少在指定的这段时间之内保持新鲜
no-transform 请求 文档在发送之前不允许被转换
only-if-cached 请求 只有当文档在缓存中才发送,不要联系原始服务器
public 响应 响应可以被任何服务器缓存
private 响应 响应可以被缓存,但只能被单个客户端访问
no-cache 响应 如果该指令伴随一个首部列表的话,那么内容可以被缓存并提供给客户端,但必须先删除所列出的首部。
如果没有指定首部缓存中的副本在没有重新向服务器验证之前不能提供给客户端
no-store 响应 响应不允许被缓存
no-transform 响应 响应在提供给客户端之前不能做任何形式的修改

must-revalidate 响应 响应在提供给客户端之前必须重新向服务器验证
proxy-revalidate 响应 共享的缓存在提供给客户端之前必须重新向原始服务器验证私有的缓存可以忽略这条指令
max-age 响应 指定文档可以被缓存的时间以及新鲜度的最长时间
s-max-age 响应 指定文档作为共享缓存时的最长使用时间(如果有max-age指令的话,以本指令为准)。私有的缓存可以忽略本指令

有条件的请求与验证码
当请求缓存服务器中的副本时,如果它不再新鲜,缓存服务器就需要保证它有一个
新鲜的副本。缓存服务器可以向原始服务器获取当前的副本。但在很多情况下,原
始服务器上的文档仍然与缓存中已过期的副本相同。
如果服务器上的文档和已过期的缓存副本相同,而缓存服务器还是要从原始服务器
上取文档的话,那缓存服务器就是在浪费网络带宽,给缓存服务器和原始服务器增
加不必要的负载,使所有事情都变慢了。
为了避免这种情况,HTTP为客户端提供了一种方法,仅当资源改变时才请求副本,
这种特殊请求称为有条件的请求。有条件的请求是标准的HTTP请求报文,但仅当
某个特定条件为真时才执行。例如,某个缓存服务器可能发送下面的有条件GET报
文给服务器,仅当文件/announce. html从2002年6月29日(这是缓存的文档最后
被作者修改的时间)之后发生改变的情况下才发送它
Get/AnnouNce. html Http/1.0
It-Modified-since: Sat, 29 Jun 2002, 14:30:00GMT
有条件的请求是通过以“If”开头的有条件的首部来实现的。在上面的例子中,有条
件的首部是If-Modifled- since(如果一从…之后一修改过)。有条件的首部使得
方法仅在条件为真时才执行。如果条件不满足,服务器就发回一个HTTP错误码。
每个有条件的请求都通过特定的验证码来发挥作用。验证码是文档实例的一个特殊
属性,用它来测试条件是否为真。从概念上说,你可以把验证码看作文件的序列号、
版本号,或者最后发生改变的日期时间。简单的说就是智能的客户端发送给
服务器的有条件的验证请求是在说:“我有版本1,如果这个资源不再是版本1就把
它发给我。”

有条件的首部 if- Modified-Since
测试的是文档实例最后被修改的日期时间,因此
我们说最后被修改的日期时间就是验证码。有条件的首部If-None- Match测试的
是文档的Eag值,它是与实体相关联的一个特殊的关键字,或者说是版本识别标
记。Last-Modified和ETag是HTTP使用的两种主要验证码。
有条件的请求类型 HTTP首部:
请求类型 验证码 描述
f- Modified- Since Last-Modified 如果在前一条响应的Last- Modified首部中说明的时间之后,资源的版本发生变化,就发送其副本
IE-Unmodified-since Last-Modified 仅在前一条响应的Last- Modified首部中说明的时间之后,资源的版本没有变化,才发送其副本
If-Match ETag 如果实体的标记与前一次响应首部中的Eag相同,就发送该资源的副本
IE-None-Match ETag 如果实体的标记与前一次响应首部中的ETag不同,就发送该资源的副本

HTTP把验证码分为两类:弱验证码( weak validators)和强验证码( strong validators)。

弱验证码不一定能唯一标识资源的一个实例,而强验证码必须如此。弱验证码的
个例子是对象的大小字节数。有可能资源的内容改变了,而大小还保持不变,因此
假想的字节计数验证码与改变是弱相关的。而资源内容的加密校验和(比如MD5)
就是强验证码,当文档改变时它总是会改变。

最后修改时间是一种弱验证码,因为尽管它说明了资源最后被修改的时间,但它的
摧述精度最大就是1秒。因为资源在1秒内可以改变很多次,而且服务器每秒可以
处理数千个请求,最后修改日期时间并不总能反应变化情况。ETag首部被当作强验
证码,因为每当资源内容改变时,服务器都可以在Eag首部放置不同的值。版本
号和摘要校验和也是很好的ETag首部候选,但它们不能带有任意的文本。ETag首
部很灵活,它可以带上任意的文本值(以标记的形式),这样就可以用来设计出各种
各样的客户端和服务器验证策略。

范围请求
关于客户端如何要求服务器只在资源的客户端副本不再有效的情况下才发送其副本
我们已经清楚地理解了。HTTP还进一步锦上添花:它允许客户端实际上只请求文
档的一部分,或者说某个范围
假设你正通过慢速的连接下载最新的热门软件,已经下了四分之三,忽然网络连接中断。
你已经为等待下载完成耽误了很久,而现在被迫要全部重头再来,祈祷着别再发生这样的倒霉事了。
有了范围请求,HTTP客户端可以通过请求曾获取失败的实体的一个范围(或者说
一部分),来恢复下载该实体。当然这有一个前提,那就是从客户端上一次请求该实
体到这次发出范围请求的时段内,该对象没有改变过。
(这就是断点续传的基本原理)

例如:
Get/BigfiLe. html Http/1.1
Host:www.joes-hardware.com
Range: bytes=4000
User-Agent: Mozilla/4. 61 [en] (WinNT: I)
客户端请求的是文档开头4000字节之后的部分(不必给出结尾字节数,
因为请求方可能不知道文档的大小)。在客户端收到了开头的4000字节之后就失败
的情况下,可以使用这种形式的范围请求。还可以用 Range首部来请求多个范围
(这些范围可以按任意顺序给出,也可以相互重叠)。例如,假设客户端同时连接到
多个服务器,为了加速下载文档而从不同的服务器下载同一个文档的不同部分。对
于客户端在一个请求内请求多个不同范围的情况,返回的响应也是单个实体,它有
一个多部分主体及content-Type: multipart/ byteranges首部。

并不是所有服务器都接受范围请求。服务器可以通过在响应中
包含cept-Range首部的形式向客户端说明可以接受的范围请求。这个首部的
值是计算范围的单位,通常是以字节计算的。例如:
Http/1.1 200 oK
Date: Fri. 05 NOv 1999 22: 35: 15 GMT
Server: Apache/1.2.4
Accept-Ranges: bytes

range首部在流行的点对点( Peer-to-Peer,p2P)文件共享客户端软件中得到广泛
应用,它们从不同的对等实体同时下载多媒体文件的不同部分。

具体应用说明:
网络中断,客户端请求续传,因此需要在HTTP头中申明本次需要续传的片段: 
Range:bytes=520200-  这个头通知服务端从文件的512K位置开始传输文件 
服务端收到断点续传请求,从文件的520200位置开始传输,并且在HTTP头中增加: 
Content-Range:bytes 520200-/524200
并且此时服务端返回的HTTP状态码应该是206,而不是200

差异编码
我们曾把网站页面的不同版本看作页面的不同实例。如果客户端有一个页面的已过
期副本,就要请求页面的最新实例。如果服务器有该页面更新的实例,就要把它发
给客户端,哪怕页面上只有一小部分发生了改变,也要把完整的新页面实例发给客
户端。
若改变的地方比较少,与其发送完整的新页面给客户端,客户端更愿意服务器只发
送页面发生改变的部分,这样就可以更快地得到最新的页面。差异编码是HTTP协
议的一个扩展,它通过交换对象改变的部分而不是完整的对象来优化传输性能。差
异编码也是一类实例操控,因为它依赖客户端和服务器之间针对特定的对象实例来
交换信息。RFC329描述了差异编码。

差异编码的结构,包括请求、生成、接收和装配文档的过程。

客户端必须告诉服务器它有页面的哪个版本,它愿意接受页面最新版的差异
( delta),它懂得哪些将差异应用于现有版本的算法。服务器必须检査它是否有这个
页面的客户端现有版本,计算客户端现有版本与最新版之间的差异(有若干算法可
以计算两个对象之间的差异)。然后服务器必须计算差异,发送给客户端,告知客户
端所发送的是差异,并说明最新版页面的新标识(Erag),因为客户端将差异应用
于其老版本之后就会得到这个版本。
客户端在If-None- Match首部中使用的是它所持有页面版本的唯一标识,这个标
识是服务器之前响应客户端时在Etag首部中发送的。客户端是在对服务器说:“如
果你那里页面的最新版本标识和这个Etag不同,就把这个页面的最新版本发给
我。”如果只有工f-None- Match首部,服务器将会把该页面的最新版本完整地发给
客户端。(假设最新版和客户端持有的版本不同。)
不过,如果客户端想告诉服务器它愿意接受该页面的差异,只要发送A-IM首部就
可以了。A-IM是 Accept-Instance-Manipulation(接受实例操控)的缩写。
形象比喻的话,客户端相当于这样说:“哦对了,我能接受某些形式的实例操控,如果你会
其中一种的话,就不用发送完整的文档给我了。”在A-IM首部中,客户端会说明它
知道哪些算法可以把差异应用于老版本而得到最新版本。服务端发送回下面这些内
容:一个特殊的响应代码—226 IM USed,告知客户端它正在发送的是所请求对象
的实例操控,而不是那个完整的对象自身;一个IM( Instance-Manipulation的缩写)
首部,说明用于计算差异的算法;新的ETag首部和 Delta-Base首部,说明用于
计算差异的基线文档的ETag(理论上,它应该和客户端之前请求里的rf-None
Match首部中的ETag相同!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值