9. 提供了可靠性操作。如果 cache 验证时不能连上源服务器,它必须返回 504(Gateway Timeout)错误信息。
"proxy-revalidate":除了不能够应用于 non-shared cache 以外,"proxy-revalidate"和"must-revalidate"的
意思是一样的。它允许在用户 cache 中保存那些经过权限认证的 response(它们 应该包含有"public"来保证
它们可以被缓存)并且在认证过同样的 request 到达时返回缓存数据而不经过源服务器验证过程;其他的则
每次都必须经过验证。
最后我们介绍一下"no-transform"规则。为了某些原因,一些 cache 服务器在保存和传输消息的时候可能
会转变实体主体的媒体类型。比如为了降低缓存空间或者在较慢的链接中减少传输流量,cache 服务器可能会
把一个图片的格式转换一下。但是某些应用场景下,数据的传输一个 bit 也不能转换,这里"no-transform"就非
常必须了。如果一个消息中包含了"no-transform",那么非修改头部及其指定的消息主体部分都不能转换或者
改变,这些非修改头部包括"Content-Location", "Content-MD5", "ETag", "Last-Modified", "Expires", "Content-
Encoding", "Content-Range", "Content-Type"(参见 HTTP 1.1 section 13.5.2)
一般说来:遵循以下基本的规则
1. 如果响应头信息:告诉缓存器不要保留缓存,缓存器就不会缓存相应内容;
2. 如果请求信息是需要认证或者安全加密的,相应内容也不会被缓存;
3. 如果在回应中不存在校验器(ETag 或者 Last-Modified 头信息),缓存服务器会认为缺乏直接的更
新度信息,内容将会被认为不可缓存。
4. 一个缓存的副本如果含有以下信息:内容将会被认为是足够新的
o 含有完整的过期时间和寿命控制头信息,并且内容仍在保鲜期内;
o 浏览器已经使用过缓存副本,并且在一个会话中已经检查过内容的新鲜度;
o 缓存代理服务器近期内已经使用过缓存副本,并且内容的最后更新时间在上次使用期之前;
o 够新的副本将直接从缓存中送出,而不会向源服务器发送请求;
5. 如果缓存的副本已经太旧了,缓存服务器将向源服务器发出请求校验请求,用于确定是否可以继续
使用当前拷贝继续服务;
3.3 Response 响应的过期与保鲜
3.3.1 age 的计算方法
先介绍一下一个响应的 age 的计算方法。
/*
* age_value: is the value of Age: header received by the cache with this response.
* date_value: is the value of the origin server's Date: header
10. * request_time: is the (local) time when the cache made the request that resulted in this cached response
* response_time: is the (local) time when the cache received the response
* now: is the current (local) time
*/
apparent_age = max(0, response_time - date_value);
corrected_received_age = max(apparent_age, age_value);
response_delay = response_time - request_time;
corrected_initial_age = corrected_received_age + response_delay;
resident_time = now - response_time;
current_age = corrected_initial_age + resident_time;
3.3.2 过期时间的计算方法
过期时间主要分为 explicit expiration time 和 heuristic expiration time,强烈建议用户指定 explicit
expiration time,因为只有网页制作者更加清楚这个网页的过期时间。
先介绍一下 explicit expiration time 的计算方法。
客户可以通过设置 Expires 或者 Cache-control 的 max-age(max-age 优先级大于 Expires)来指定
explicit expiration time。我们测试了 html 和 php 语言设置 Expires 的方法,并且使用 ethereal 观察了传输的
HTTP 信息,在我们的环境下,发现使用 html 设置 header meta 不能反映到 HTTP header 中去,而 php 的
header()函数则能够成功。
php 设置 HTTP 头的方法很简单,只要调用函数 header()就可以了,假如我们新建一个名为
testHeader.php 的文件并将其内容修改为:
<?php
$offset = 3600 * 24;
$expire = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
Header($expire);