条件GET方法(The Conditional GET)
尽管缓存可以减少用户感知到的响应时间,但是缓存引入了一个新的问题。
存储在cache中的对象可能是陈旧的。换句话说,自从对象的副本被缓存到这个cache,存储在web服务器端的对象可能被修改过。
幸运的是,HTTP提供了条件GET(conditional GET)机制
,这个机制使得cache能够确认它的对象是最新的。
什么样的HTTP请求报文属于条件请求报文呢?
(1)请求报文使用了GET方法
(2)请求报文包括了一个If-Modified-Since头行
为了展示一下条件GET是如何运作的,我们还是举一个例子。
1.代理服务器代表请求浏览器发送一条请求报文给web server
GET /fruit/kiwi.gif HTTP/1.1
Host: www.exotiquecuisine.com
2.Web 服务器将带有请求对象的响应报文发送给cache
HTTP/1.1 200 OK
Date: Sat, 8 Oct 2011 15:39:29
Server: Apache/1.3.0 (Unix)
Last-Modified: Wed, 7 Sep 2011 09:23:24
Content-Type: image/gif
(data data data ...)
cache将这个对象转发给请求的浏览器并且将这个对象缓存到自己的本地存储。重要的是,cache将这个对象上次修改的时间也存储了起来。
3.一周之后,另一个浏览器通过cache请求了相同的对象,并且这个对象仍然在cache里。由于这个对象可能在过去的一周里被修改过,cachejiu 就发起一个conditional GET来做一个更新检查。
具体的报文如下
GET /fruit/kiwi.gif HTTP/1.1
Host: www.exotiquecuisine.com
If-modified-since: Wed, 7 Sep 2011 09:23:24
注意If-modified-since的值就是一周前Last-Modified的值。这个条件GET告诉服务器仅在对象在这个时间之后被修改的情况下才发送这个对象给我。
假定这个对象自从一周前没有被修改过,那么第4步:
4.Web服务器就会发送一个响应报文
HTTP/1.1 304 Not Modified
Date: Sat, 15 Oct 2011 15:39:29
Server: Apache/1.3.0 (Unix)
(empty entity body)
我们可以看到,在回复条件GET时,web server依然发送 了一个响应报文但是并没有在响应消息中包含请求的对象。包含请求的对象会浪费带宽,增加用户感知响应时间。
注意,最后一条响应报文有一个304的状态码,意思是Not Modified。这也就告知了缓存它可以继续了,将这个对象的cached copy发送给请求的browser.