HTTP 通常用于分布式信息系统,通过使用响应缓存可以提高性能。HTTP/1.1 协议包括一些元素,旨在使缓存尽可能好地工作。因为这些元素与协议的其他方面密不可分,而且它们之间相互影响,所以将 HTTP 的基本缓存设计与方法、头、响应码等的详细描述分开来描述是很有用的。
缓存如果不能显著提高性能,那就没有用了。HTTP/1.1 中缓存的目标是在许多情况下消除发送请求的需要,并在其他许多情况下消除发送完整响应的需要。前者减少了许多操作所需的网络往返次数;我们为此使用了一种 “过期” 机制(见第 13.2 节)。后者减少了对网络带宽的要求;为此我们使用了一个 “验证” 机制(见第 13.3 节)。
对性能、可用性和断开连接的操作的要求要求我们能够放宽语义透明的目标。 HTTP/1.1 协议允许源服务器、缓存和客户端在必要时显式降低透明度。 但是,由于不透明的操作可能会使非专家用户感到困惑,并且可能与某些服务器应用程序(例如订购商品的应用程序)不兼容,因此协议要求放宽透明度:
- 仅在客户端或源服务器放宽时通过显式协议级别请求仅在缓存或客户
- 仅在缓存或客户端放宽时向最终用户发出明确警告。
因此,HTTP1.1 提供了以下要素:
- 当各方需要时提供完全语义透明性的协议功能。
- 允许源服务器或用户代理显式请求和控制非透明操作的协议功能。
- 允许缓存将警告附加到不保留请求的语义透明度近似的响应的协议功能。
一个基本原则是客户端必须能够检测到语义透明度的任何潜在放松。
注意:服务器、缓存或客户端实现者可能会面临本规范中没有明确讨论的设计决定。如果某个决定可能会影响到语义透明度,那么实现者应该偏向于维持透明度,除非经过仔细和完整的分析,发现破坏透明度会带来很大的好处。
13.1.1 缓存的正确性
一个正确的缓冲区必须用缓冲区持有的适合该请求的最新响应来响应请求(见第 13.2.5、13.2.6 和 13.12 节),该响应满足以下条件之一:
通过与源服务器重新验证响应,已经检查了它与原点服务器所返回的内容是否相等(第 13.3 节)。
它是 “足够新鲜的”(见第 13.2 节)。在默认情况下,这意味着它满足了客户端、源服务器和缓存的最小限制性的新鲜度要求(见第 14.9 节);如果源服务器这样指定,它就是源服务器单独的新鲜度要求。
如果按照客户和源服务器的最严格的新鲜度要求,存储的响应不够 “新鲜”,在经过仔细考虑的情况下,缓存可能仍然会返回带有适当警告头的响应(见第 13.1.5 节和 14.46 节),除非这样的响应被禁止(例如,通过 “no-store” 缓存指令,或通过 “no-cache” 缓存请求指令;见第 14.9 节)。
- 它是一个适当的 304(Not Modified)、305(Proxy Redirect)或错误(4xx 或 5xx)响应信息。
如果缓存不能与源服务器通信,那么如果响应可以从缓存中正确提供,那么正确的缓存应该像上面那样响应;如果不能,它必须返回一个错误或警告,表明有一个通信失败。
如果高速缓存收到它通常会转发给请求客户端的响应(无论是整个响应,还是304(Not Modified)响应),并且收到的响应不再新鲜,高速缓存应该将其转发给请求客户端,而不添加新的警告(但不删除任何现有的 Warning 头)。缓存不应该仅仅因为一个响应在传输过程中变得陈旧而试图重新验证该响应;这可能导致无限循环。收到没有 Warning 的陈旧响应的用户代理可能会向用户显示一个警告指示。
13.1.2 Warning
每当缓存返回的响应既不是第一手的也不是 “足够新鲜” 的(在第 13.1.1 节中条件 2 的意义上),它必须使用Warning 通用头来附加一个警告,以达到这个效果。Warning 头和当前定义的警告在第 14.46 节中描述。该警告允许客户采取适当的行动。
警告可以用于其他目的,包括与缓存有关的和其他的。使用警告,而不是错误状态代码,可以将这些响应与真正的失败区分开来。
警告被指定为三位数的警告代码。第一个数字表示在成功的重新验证后,该警告必须或不必须从存储的缓存条目中删除:
1xx 描述响应的新鲜度或重新验证状态的警告,因此在重新验证成功后必须被删除。1XX 警告代码可能只在验证一个缓存条目时由缓存生成。它决不能由客户端生成。
2xx 描述实体或实体头的某些方面的警告,这些警告没有被重新验证所纠正(例如,实体的有损压缩),并且在成功重新验证后不得被删除。
关于代码本身的定义,见第 14.46 节。
HTTP/1.0 缓存将缓存响应中的所有警告,而不删除第一类中的警告。传递给 HTTP/1.0 缓存的响应中的警告带有一个额外的 warning-date 字段,这可以防止未来的 HTTP/1.1 接收者相信一个被错误地缓存的警告。
警告也有一个警告文本。该文本可以是任何适当的自然语言(也许基于客户端的接受头文件),并包括一个可选择的使用何种字符集的指示。
一个响应可以附加多个警告(无论是由源服务器还是由缓冲区),包括具有相同代码的多个警告。例如,一个服务器可能提供相同的警告,并同时提供英语和巴斯克语的文本。
当一个响应附有多个警告时,向用户显示所有的警告可能是不实际的或不合理的。这个版本的 HTTP 没有规定严格的优先级规则来决定显示哪些警告和以什么顺序显示,但建议使用一些启发式方法。