Expires(过期时间)
Http 头信息设置过期时间,一般是设置一个时间点,例如:
Expires:Tue Jul 28 11:00:00 CST 2011 (2011/7/28)
一般使用在静态文件,例如img、js、css等。
要注意的:如果设置的过期时间是一个固定的时间,在返回内容的时候又没有连带更新下次过期的时间,那么之后都会请求服务器,反而增加了负载和响应时间。
Cache-Control(缓存控制)
缓存控制,使用起来更为灵活、功能更强大。
l max-age=[秒] — 执行缓存被认为是最新的最长时间。类似于过期时间,这个参数是基于请求时间的相对时间间隔,而不是绝对过期时间,[秒]是一个数字,单位是秒:从请求时间开始到过期时间之间的秒数。
l s-maxage=[秒] — 类似于max-age属性,除了他应用于共享(如:代理服务器)缓存
l public — 标记认证内容也可以被缓存,一般来说:经过HTTP认证才能访问的内容,输出是自动不可以缓存的;
l private — 指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
l no-cache — 强制每次请求直接发送给源服务器,而不经过本地缓存版本的校验。这对于需要确认认证应用很有用(可以和public结合使用),或者严格要求使用最新数据的应用(不惜牺牲使用缓存的所有好处);
l no-store — 强制缓存在任何情况下都不要保留任何副本
l must-revalidate — 告诉缓存必须遵循所有你给予副本的新鲜度的,HTTP允许缓存在某些特定情况下返回过期数据,指定了这个属性,你高速缓存,你希望严格的遵循你的规则。
l proxy-revalidate — 和 must-revalidate类似,除了他只对缓存代理服务器起作用
l min-fresh 指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
l max-stale 指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
可以在ajax返回结果中加缓存,以及一些请求加缓存,这个需要程序实现。
Last-Modified
在第一次请求时服务器会返回一个200状态以及响应正文,同时在响应头中会有Last-Modified 信息,例如:Last-Modified: Mon, 25 Jul 2011 02:01:46 GMT
在第二次请求该URL时浏览器会在请求头信息中发送If-Modified-Since 信息,例如:
If-Modified-Since: Wed, 20 Jul 201106:31:59 GMT,如果服务器资源没有发生变化则返回304状态,如果有变化则返回响应正文。
Etag
Etag是配合If-None-Match来使用的,在服务器响应头信息中加入Etag,如:
Etag W/"1795-1310539468000",在请求头信息中加入If-None-Match发送etag信息到服务器,如:If-None-Match W/"1795-1310539468000",可以通过服务器配置来实现,也可以通过程序来实现。
对静态文件生成版本引用
封装成标签来统一生成html代码,基本思路是根据文件的名称(包括路径)当做key,文件的最后更新时间当做value存储在内存中,每次的html代码都从内存中获取版本信息来生成引用的html代码。
可以优化
1. 现有的static服务器缓存设置似乎有点问题,静态文件应该直接在客户端获取缓存,而不应该每次去服务器去校验返回304状态码。
HTTP/1.0304 Not Modified
Date:Sun, 24 Jul 2011 15:49:13 GMT
Content-Type:application/x-javascript; charset=utf-8
Expires: Sun, 24 Jul 2011 16:49:06 GMT
Last-Modified: Tue, 14 Dec 2010 03:22:35 GMT
Cache-Control:max-age=3600
X-Via:1.0 shnh222:8106 (Cdn Cache Server V2.0)
Age:142178
Warning:113 proxy1.staff.woyo.com (squid/3.1.9) This cache hit is still fresh and morethan 1 day old, 110 squid/3.1.9 "Response is stale", 111 squid/3.1.9"Revalidation failed"
X-Cache:HIT from proxy1.staff.woyo.com
Via: 1.0proxy1.staff.woyo.com (squid/3.1.9)
Connection: keep-alive
可以看出设置应该在2011年7月24 16:49:06 过期,也就是说现在访问该缓存已经过期!
为什么是304状态呢?
因为在响应头信息中Last-Modified: Tue, 14 Dec 2010 03:22:35 GMT,而在请求头信息中有:If-Modified-SinceTue,14 Dec 2010 03:22:35 GMT,也就说客户端实际去访问了服务器,服务器检测到该文件并没有修改过所以返回304状态码。
我们想要做到的是,一些js、css、img等静态文件信息直接在客户端缓存。
2. 在ajax以及页面的请求响应中加入Cache-Control 来控制缓存。
3. Etag可以使用在静态文件也可以用在页面请求,静态文件可以直接nginx中配置,页面请求的需要程序来完成。
Nginx配置 http://mikewest.org/2008/11/generating-etags-for-static-content-using-nginx
总结
1. Last-Modified, Etag条件缓存控制参数,需要和服务器请求查看资源是否改变,可以减少资源的下载量,但是不会减少请求数。
2. Expires,Cache-Control过期时间设置,同时设置时Cache-Control会覆盖Expires(只限于普通请求,如:链接点击跳转、用JS脚本打开新页面、使用iframe时),如果F5或者Ctrl+F5则忽略过期时间的设定。
3. 如果同时设置了过期时间和控制参数,在未过期时间内读取缓存不发起请求,过期后则发起请求,过期时间级别高于控制参数。
4. no-cache在IE中有效,no-store在firefox中有效,一般同时设置2个,如:
Cache-Control: no-cache, no-store。
附
表1 Cache-Control可设置值
值
说明
max-age=xxx
缓存的内容将在 xxx 秒后失效 , 这个选项只在 HTTP 1.1 可用 , 并如果和 Expires、Last-Modified 一起使用时 , 优先级较高
must-revalidation/
proxy-revalidation
如果缓存的内容失效,请求必须发送到服务器 / 代理以进行重新验证
no-store
所有内容都不会被缓存到缓存或 Internet 临时文件中
no-cache
所有内容都不会被缓存
private
内容只缓存到私有缓存中
public
所有内容都将被缓存
总结:
打开新窗口
如果指定 cache-control 的值为 private 、 no-cache 、 must-revalidate, 那么打开新窗口访问时都会重新访问服务器。而如果指定了 max-age 值 , 那么在此值内的时间里就不会重新访问服务器 , 例如: Cache-control: max-age=5 表示当访问此网页后的 5 秒内再次访问不会去服务器
在地址栏回车
如果值为 private 或 must-revalidate, 则只有第一次访问时会访问服务器 , 以后就不再访问。如果值为 no-cache, 那么每次都会访问。如果值为 max-age, 则在过期之前不会重复访问。
按后退按扭
如果值为 private 、 must-revalidate 、 max-age, 则不会重访问 , 而如果为 no-cache, 则每次都重复访问
按刷新按扭
无论为何值 , 都会重复访问