Cache是一种常见的提高系统的运行效率的方法。在HTTP/1.1中,通过Cache的Expiration机制,让尽可能减少由Client向Server发送请求的次数。这篇博客简单介绍HTTP Header中与Expiration相关的字段。
1. Expires
Expires早就存在于HTTP/1.0,是由服务器指定的Response过期时间。表明在Expires这个时间点之前,返回的response都是足够新的或者说是有效的,Client无需再向Server发送请求。Expires表示的是一个绝对的时刻,所以,每次返回的Expires的时间极有可能都不一样。
下面就用一个例子作为演示:
我首先自己写了一个简单的Servlet,这个Servlet在HTTP response头部中塞入了Expires信息。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
long now = System.currentTimeMillis();
resp.setDateHeader("Expires", now + 3600000);
...
}
当Server启动以后,我们用Firefox作为工具检测我们的请求发送情况以及收到的包头信息。
当我通过Firefox第一次打开 http://localhost:8080/httpdemo 时,服务器返回的头部包括了
Expires: "Mon, 31 Mar 2014 18:31:35 GMT"
Expires值表明,在"Mon, 31 Mar 2014 18:31:35 GMT"这个时间之前,这个返回值都是有效的。Client无需再去从Server取信息。如下图所示:
需要注意的是,这里的Expires指示告诉Client如果这个response没有过期,没有必要再次访问。但这并不意味着response过期之前,Client不能向Server发送请求。同时,Expires也不意味在response过期以后,Client需要主动的去Server取最新的消息。
2. Cache-control: max-age
在HTTP/1.1这个标准中引入了一个新的字段Cache-control。Cache-control中有一条指令,叫max-age。
Age表示这个Response已经存活了多久了。而max-age表示response最大的存活时间。所以,max-age表明了这条被cache的消息在多长时间段内是有效的。
下面就简单的用一个例子来做演示:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.addHeader("Cache-Control", "max-age=3600");
...
}
我们访问 http://localhost:8080/httpdemo/ 以后,服务器返回的response中包含了
Cache-Control: "max-age=3600"
表示这个response生成以后一个小时之内都不会过期,也就不需要再向服务器发送请求了。
如果返回的消息中,同时出现了Cache-control: max-age和Expires,那么以Cache-control: max-age为准,Expires的声明将会被覆盖掉。
3. 更多
可能有比较调皮的同学,用Chrome试了前面的Expires例子,发现Chrome再次向服务器发送了请求。这是为什么呢?我们先看看截取到的request:
我们发现Request中的max-age是0,那么当max-age出现在request中的时候,服务器又会做些什么呢?
Cache中的Expiration机制还有非常多可以讲的东西,但是最最基本的东西就前面的这么一点儿,想要更多的了解Cache中的age计算,可以参考下面提供的链接,都是非常好的详尽参考资料。
参考资料:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.11
http://www.bitsandpix.com/entry/java-servlet-set-expires-header-with-cache-control/