15.8 验证码和新鲜度

  • 当文档在客户端“过期”之后(也就是说,客户端不再认为该副本有效),客户端必须从服务器请求一份新的副本。不过,如果该文档在服务器上并未发生改变,客户端也就不需要再接收一次了——继续使用缓存的副本即可。
  • 这种特殊的请求,称为有条件的请求(conditional request),要求客户端使用验证码(validator)来告知服务器它当前拥有的版本号,并仅当它的当前副本不再有效时才要求发送新的副本。

1. 新鲜度

  • 服务器应当告知客户端能够将内容缓存多长时间,在这个时间之内就是新鲜的。
  • 服务器可以用这两个首部之一来提供这种信息: Expires(过期) 和 Cache-Control(缓存控制)。
  • 缓存和新鲜度在第 7 章中曾有详细讨论。
  • Cache-Control首部的指令:
指令报文类型描述
no-cache请求在重新向服务器验证之前,不要返回文档的缓存副本
no-store请求不要返回文档的缓存副本。不要保存服务器的响应
max-age请求缓存中的文档不能超过指定的使用期
max-stale请求文档允许过期(根据服务器提供的过期信息计算),但不能超过指令中指定的过期值
min-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 指 令的话,以本指令为准)。私有的缓存可以忽略本指令

2. 有条件的请求与验证码

  • 当请求缓存服务器中的副本时,如果它不再新鲜,缓存服务器就需要保证它有一个新鲜的副本。缓存服务器可以向原始服务器获取当前的副本。但在很多情况下,原始服务器上的文档仍然与缓存中已过期的副本相同。若此时依然去获取文档,会增加服务器不必要的负担。
  • 为了避免这种情况,HTTP 为客户端提供了一种方法,仅当资源改变时才请求副本,这种特殊请求称为有条件的请求。有条件的请求是标准的 HTTP 请求报文,但仅当某个特定条件为真时才执行。
  • 有条件的请求是通过以“If-”开头的有条件的首部来实现的。有条件的首部使得方法仅在条件为真时才执行。如果条件不满足,服务器就发回一个 HTTP 错误码。在第 7 章也有阐述。
  • 每个有条件的请求都通过特定的验证码来发挥作用。验证码是文档实例的一个特殊属性,用它来测试条件是否为真。从概念上说,你可以把验证码看作文件的序列号、版本号,或者最后发生改变的日期时间。
  • 比如:有条件的首部 If-Modified-Since 测试的是文档实例最后被修改的日期时间,因此我们说最后被修改的日期时间就是验证码。有条件的首部 If-None-Match 测试的是文档的 ETag 值,它是与实体相关联的一个特殊的关键字,或者说是版本识别标 记。Last-Modified 和 ETag 是 HTTP 使用的两种主要验证码。
  • 下表列出了用于有条件请求的 4 种 HTTP 首部。每个有条件的首部之后就是这种首部所用的验证 码类型:
请求类型验证码描述
If-Modified-SinceLast-Modified如果在前一条响应的 Last-Modified 首部中说明的时间之后,资源的版本发生变化,就发送其副本
If-Unmodified-SinceLast-Modified仅在前一条响应的 Last-Modified 首部中说明的时间之后,资源的版本没有变化,才发送其副本
If-MatchETag如果实体的标记与前一次响应首部中的 ETag 相同,就发送该资源的副本
If-None-MatchETag如果实体的标记与前一次响应首部中的 ETag 不同,就发送该资源的副本
  • HTTP 把验证码分为两类:弱验证码(weak validators)和强验证码(strong validators)。弱验证码不一定能唯一标识资源的一个实例,而强验证码必须如此。弱验证码的一个例子是对象的大小字节数。有可能资源的内容改变了,而大小还保持不变,因此假想的字节计数验证码与改变是弱相关的。而资源内容的加密校验和(比如 MD5)就是强验证码,当文档改变时它总是会改变。
  • 最后修改时间被当作弱验证码,因为尽管它说明了资源最后被修改的时间,但它的描述精度最大就是 1 秒。因为资源在 1 秒内可以改变很多次,而且服务器每秒可以处理数千个请求,最后修改日期时间并不总能反应变化情况。
  • ETag 首部被当作强验证码,因为每当资源内容改变时,服务器都可以在 ETag 首部放置不同的值。版本号和摘要校验和也是很好的 ETag 首部候选,但它们不能带有任意的文本。ETag 首部很灵活,它可以带上任意的文本值(以标记的形式),这样就可以用来设计出各种各样的客户端和服务器验证策略。
  • 有时候,客户端和服务器可能需要采用不那么精确的实体标记验证方法。例如,某服务器可能想对一个很大、被广泛缓存的文档进行一些美化修饰,但不想在缓存服务器再验证时产生很大的传输流量。在这种情况下,该服务器可以在标记前面加上“W/”前缀来广播一个“弱”实体标记。对于弱实体标记来说,只有当关联的实体在语义上发生了重大改变时,标记才会变化。而强实体标记则不管关联的实体发生了什么性质的变化,标记都一定会改变。
  • 概括一下,当客户端多次访问同一个资源时,首先需要判断它当前的副本是不是仍然新鲜。如果不再新鲜,它们就必须从服务器获取最新的版本。为了避免在资源没有改变的情况下收到一份相同的副本,客户端可以向服务器发送有条件的请求,说明能唯一标识客户端当前副本的验证码。只在资源和客户端的副本不同的情况下服务器才会发送其副本。更多关于缓存再验证的细节,请回顾 7.5 节。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值