4月阅读周·HTTP权威指南:实体和编码之随时间变化的实例篇
引言
HTTP(Hypertext Transfer Protocol,超文本传输协议)是在万维网上进行通信时所使用的协议方案。HTTP有很多应用,但最著名的是用于Web浏览器和Web服务器之间的双工通信。
《HTTP权威指南》一书将HTTP中一些互相关联且常被误解的规则梳理清楚,并编写了一系列基于各种主题的章节介绍HTTP各方面的特性。纵观全书,对HTTP“为什么”这样做进行了详细的解释,而不仅仅停留在它是“怎么做”的。此外,这本书还介绍了很多HTTP应用程序正常工作所必需且重要的非HTTP技术。
这本书主要包括以下内容:
- 第一部分描述了Web的基础构件与HTTP的核心技术
- 第二部分重点介绍了Web系统的结构构造块:HTTP服务器、代理、缓存、网关以及机器人应用程序。
- 第三部分提供了一套用于追踪身份、增强安全性以及控制内容访问的技术和技巧。
- 第四部分涵盖HTTP报文主体和Web标准,前者包含实际内容,后者描述并处理主体内容。
- 第五部分介绍了发布和传播Web内容的技巧。
- 第六部分是一些很有用的参考附录,以及相关技术的教程。
实体和编码
每天都有数以亿计的各种媒体对象经由HTTP传送,如图像、文本、影片以及软件程序等。只要你能叫出名字,HTTP就可以传送。HTTP还会确保它的报文被正确传送、识别、提取以及适当处理。
主要包括以下内容:
- 作为HTTP数据的容器,HTTP报文实体有哪些格式和行为。
- HTTP如何描述实体的主体大小,HTTP为确定大小制定了哪些规则。
- 为了使客户端正确处理内容,使用了哪些实体首部来描述内容的格式、字母和语言。
- 可逆的内容编码,发送方可以在发送之前用它来转换内容的数据格式,使其占用更小的空间,或者更安全。
- 传输编码和分块编码。传输编码可以改变HTTP传输数据的方式,以改善某些类型内容的通信能力。分块编码是一种特殊的传输编码,它把数据切分为若干块,这样可以更可靠地传输长度未知的内容。
- 标记、标签、时间以及校验和等一整套机制,帮助客户端获取所请求内容的最新版本。
- 可用作内容版本号的验证码,网站应用可以通过它确保接收最新的内容。还有设计用来控制对象新鲜度的各种HTTP首部字段。
- 范围,在恢复中断的传输方面很有用。
- HTTP差异编码扩展,它使客户端只需要请求网页中和前一次相比有改变的部分。
- 实体主体的校验和,可以用来检测经过若干代理之后,实体的内容是否发生了改变。
随时间变化的实例
网站对象并不是静态的。同样的URL会随着时间变化而指向对象的不同版本。以CNN的主页为例,同一天里多次访问cnn的网址,可能每次得到的返回页面都会略有不同。
可以把CNN的主页当作一个对象来考虑,其不同版本就可以看作这个对象的不同实例。客户端多次请求同一个资源(URL),但得到的是该资源的不同实例,因为它是随时间而变化的。在时间(a)和时间(b)具有相同的实例,而在时间(c)则是不同的实例。
验证码和新鲜度
客户端起初没有该资源的副本,因此它发送请求给服务器要求得到一份。服务器用该资源的版本1给以响应。客户端现在可以缓存这份副本,但是要缓存多长时间呢?
当文档在客户端“过期”之后(也就是说,客户端不再认为该副本有效),客户端必须从服务器请求一份新的副本。不过,如果该文档在服务器上并未发生改变,客户端也就不需要再接收一次了——继续使用缓存的副本即可。
这种特殊的请求,称为有条件的请求(conditional request),要求客户端使用验证码(validator)来告知服务器它当前拥有的版本号,并仅当它的当前副本不再有效时才要求发送新的副本。
新鲜度
服务器应当告知客户端能够将内容缓存多长时间,在这个时间之内就是新鲜的。服务器可以用这两个首部之一来提供这种信息:Expires(过期)和Cache-Control(缓存控制)。
Expires首部规定文档 “过期”的具体时间——此后就不应当认为它还是最新的。Expires首部的语法如下:
Expires: Sun Mar 18 23:59:59 GMT 2001
客户端和服务器为了能正确使用Expires首部,它们的时钟必须同步。这并不总是很容易的,因为它们可能都没有运行像Network Time Protocol(网络时间协议,NTP)这样的时钟同步协议。用相对时间来定义过期的机制会更有用。Cache-Control首部可以用秒数来规定文档最长使用期——从文档离开服务器之后算起的总计时间。使用期不与时钟同步,因此可以给出更精确的结果。
实际上,Cache-Control首部功能很强大。服务器和客户端都可以用它来说明新鲜度,并且除了使用期或过期时间之外,还有很多指令可用。
有条件的请求与验证码
当请求缓存服务器中的副本时,如果它不再新鲜,缓存服务器就需要保证它有一个新鲜的副本。缓存服务器可以向原始服务器获取当前的副本。但在很多情况下,原始服务器上的文档仍然与缓存中已过期的副本相同。我们看到过这种情况;缓存的副本或许已经过期了,但原始服务器上的内容与缓存的内容仍然相同。如果服务器上的文档和已过期的缓存副本相同,而缓存服务器还是要从原始服务器上取文档的话,那缓存服务器就是在浪费网络带宽,给缓存服务器和原始服务器增加不必要的负载,使所有事情都变慢了。
为了避免这种情况,HTTP为客户端提供了一种方法,仅当资源改变时才请求副本,这种特殊请求称为有条件的请求。有条件的请求是标准的HTTP请求报文,但仅当某个特定条件为真时才执行。例如,某个缓存服务器可能发送下面的有条件GET报文给服务器,仅当文件/announce.html从2002年6月29日(这是缓存的文档最后被作者修改的时间)之后发生改变的情况下才发送它:
GET /announce.html HTTP/1.0
If-Modified-Since: Sat, 29 Jun 2002, 14:30:00 GMT
有条件的请求是通过以“If-”开头的有条件的首部来实现的。在上面的例子中,有条件的首部是If-Modified-Since(如果 -从……之后 -修改过)。有条件的首部使得方法仅在条件为真时才执行。如果条件不满足,服务器就发回一个HTTP错误码。
每个有条件的请求都通过特定的验证码来发挥作用。验证码是文档实例的一个特殊属性,用它来测试条件是否为真。从概念上说,你可以把验证码看作文件的序列号、版本号,或者最后发生改变的日期时间。
有条件的首部If-Modified-Since测试的是文档实例最后被修改的日期时间,因此我们说最后被修改的日期时间就是验证码。有条件的首部If-None-Match测试的是文档的ETag值,它是与实体相关联的一个特殊的关键字,或者说是版本识别标记。Last-Modified和ETag是HTTP使用的两种主要验证码。
HTTP把验证码分为两类:弱验证码(weak validators)和强验证码(strong validators)。弱验证码不一定能唯一标识资源的一个实例,而强验证码必须如此。弱验证码的一个例子是对象的大小字节数。有可能资源的内容改变了,而大小还保持不变,因此假想的字节计数验证码与改变是弱相关的。而资源内容的加密校验和(比如MD5)就是强验证码,当文档改变时它总是会改变。
最后修改时间被当作弱验证码,因为尽管它说明了资源最后被修改的时间,但它的描述精度最大就是1秒。因为资源在1秒内可以改变很多次,而且服务器每秒可以处理数千个请求,最后修改日期时间并不总能反应变化情况。ETag首部被当作强验证码,因为每当资源内容改变时,服务器都可以在ETag首部放置不同的值。版本号和摘要校验和也是很好的ETag首部候选,但它们不能带有任意的文本。ETag首部很灵活,它可以带上任意的文本值(以标记的形式),这样就可以用来设计出各种各样的客户端和服务器验证策略。
有时候,客户端和服务器可能需要采用不那么精确的实体标记验证方法。例如,某服务器可能想对一个很大、被广泛缓存的文档进行一些美化修饰,但不想在缓存服务器再验证时产生很大的传输流量。在这种情况下,该服务器可以在标记前面加上“W/”前缀来广播一个“弱”实体标记。对于弱实体标记来说,只有当关联的实体在语义上发生了重大改变时,标记才会变化。而强实体标记则不管关联的实体发生了什么性质的变化,标记都一定会改变。
总结
HTTP协议规定了称为实例操控(instance manipulations)的一系列请求和响应操作,用以操控对象的实例。两个主要的实例操控方法是范围请求和差异编码。这两种方法都要求客户端能够标识它所拥有(如果有的话)的资源的特定副本,并在一定的条件下请求新的实例。
作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞 | 收藏⭐️ | 留言。
- 随机文章
- 热门文章
- 热评文章
- 探索自我:深入了解你的性格特点和行为模式部队文职心理测试题目
- 青少年心理健康测试:评估与促进青少年心理发展青少年心理健康测试网站
- 免费测你的性格和《三叉戟》中的谁最像
- Java 分布式缓存系统
- 性格小测试 测试你的性格狠吗
- 从Intel IXP网络处理器到DPDK技术的演进
- 性格测一测 测你最大的优点及才华
- Java 学校课程管理系统
- 性格测试 测一测你戴着什么样的性格面具