本文共 5408 字,大约阅读时间需要 18 分钟。
通用首部字段是指,请求报文和响应报文双方都会使用的首部字段。
一,Cache-Control
通过指定首部字段Cache-Control的指令,就能操作缓存的工作机制。
Cache-Control指令一览
缓存请求指令
缓存响应指令
*多个指令之间通过逗号‘,’分隔。
下面我们通过指令的特点分别来介绍上述指令
(1) 表示是否能缓存的指令
public指令
Cache-Control: public
当指定使用public指令时,则表明其他用户也可以利用缓存。
private指令
Cache-Control: private
当指定private指令后,响应只以特定的用户作为对象。也就是说,缓存服务器会对该特定用户提供资源缓存的服务,对于其他用户送过来的请求,代理服务器则不会返回缓存。
no-cache指令
Cache-Control: no-cache
使用no-cache指令的目的是为了防止从缓存中返回过期的资源。
客户端发送的请求中如果包含no-cache指令,则表示客户端将不会接受缓存过的响应。于是,中间缓存服务器必须把客户端请求转发给源服务器。
服务器返回的响应中如果包含no-cache指令,那么缓存服务器不能对资源进行缓存。
Cache-Control; no-cache=Location
如上例,服务器返回的响应中,若no-cache指令具体指定参数值,那么客户端在接收对应的响应报文时就不能进行缓存。换言之,无参数的值的首部字段客户端就可以使用缓存。(只能在响应指令中指定该参数)
(2)控制可执行缓存的对象的指令
no-store指令
Cache-Control:no-store
当使用no-store指令时,暗示请求(和对应的响应)或响应中包含机密信息。
因此,该指令规定缓存不能在本地存储请求或响应的任一部分。
(3)指定缓存期限和认证的指令
s-maxage指令
Cache-Control:s-maxage=604800(单位:秒)
s-maxage指令的功能和max-age指令的相同(见下面),不同点是s-maxage指令只适用于供多位用户使用的公共缓存服务器。也就是说,对于向同一用户重复返回响应的缓存服务器来说,这个指令没有任何作用。
max-age指令
Cache-Control:max-age=604800
当客户端发送的请求中包含max-age指令时,如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接受缓存的资源。(不难推理出,当max-age=0时,客户端不会接受缓存)
当服务器返回的响应中包含max-age指令时,缓存服务器将不对资源的有效性再做确认,而max-age数值代表资源保存为缓存的最长时间。
*如果首部字段中同时包含以上两个指令,则优先处理s-maxage指令。
min-fresh指令
Cache-Control:min-fresh=60
min-fresh指令要求缓存服务器返回至少还未过指定时间的缓存资源。
比如,当指定min-fresh为60秒后,在这60秒以内如果有超过有限期限的资源都无法作为响应返回了。
max-stale 指令
Cache-Control:max-stale=3600
使用max-stale指令可指示缓存资源,即使过期也照常接收。
如果指令未指定参数值,那么无论经过多久,客户端都会接收缓存的响应;如果指定了参数值,那么就算过期,只要仍处于max-stale指定的时间内,仍旧会被客户端接收。
only-if-cached指令
Cache-Control:only-if-cached
使用only-if-cached指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。也就是说,该指令要求缓存服务器不重新加载响应,也不会再次确认响应的有效性。若发生请求缓存服务器的本地缓存无响应,则返回状态码504 Gateway Timeout。
must-revalidate指令
Cache-Control:must-revalidate
使用must-ravalidate指令,代理会向源服务器再次验证即将返回的响应缓存目前是否仍有效。
若代理无法连通源服务器再次获取有效资源的话,缓存必须给客户端一条 504状态码。
另外,使用must-revalidata指令会忽略请求的max-stale指令。
proxy-revalidate指令
Cache-Control:proxy-revalidate
proxy-revalidate指令要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。
no-transform指令
Cache-Control:no-transform
使用no-transform指令规定无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型。(这样做可防止缓存或代理压缩图片等类似操作)
(4)Cache-Control扩展
cache-extension token
Cache-Control:private,community="UCI"
通过cache-extension标记(token),可以扩展Cache-Control首部字段内的指令。
如上例,Cache-Control首部字段本身没有community这个指令,借助extension tokens实现了该指令的添加。如果缓存服务器不能理解这个新指令,就会直接忽略。因此,extension tokens仅对能理解它的缓存服务器来说是有意义的。
二,Connection
Connection首部字段具备如下两个作用。
.控制不再转发给代理的首部字段
.管理持久连接
(1)控制不再转发给代理的首部字段
Connection:不再转发的首部字段名(即Hop-by-hop首部:参见6.1节)
举例:
客户端发送请求报文:
GET / HTTP/1.1
Upgrade: HTTP/1.1
Connection: Upgrade
经过代理后请求报文将变化如下:
GET / HTTP/1.1
也就是说,首部字段Upgrade被删除后再转发。 由此我们可以看出,在客户端发送请求和服务器返回响应内,使用Connection首部字段,可控制不再转发给代理的首部字段(即Hop-by-hop首部。)
(2) 管理持久连接(持久连接见2.4节)
Connection:close
在HTTP/1.1之前的HTTP版本的默认连接都是非持久连接。为此,如果想在旧版本的HTTP协议上维持持续连接,则需要指定Connection首部字段的值为Keep-Alive。
举例:
客户端发送请求报文:
GET / HTTP/1.0
Connection:Keep-Alive
服务器返回响应报文:
HTTP/1.1 200 OK
...
Keep-Alive: timeout=10, max=500
Connection: Keep-Alive
...
如上例所示,客户端发送请求给服务器时,服务器端会向上例所示那样加上首部字段Keep-Alive及首部字段Connection后返回响应。
而HTTP/1.1 版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器想明确断开连接时,则指定Connection首部字段值为close。
三,Date
首部字段Date表明创建HTTP报文的日期和时间。
HTTP/1.1协议的日期时间格式:
Date: Tue, 03 Jul 2010 04:40:59 GMT
四,Pragma
Pragma是HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。
Pragma: no-cache
虽然该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户端要求所有中间服务器不返回缓存的资源。
如果所有中间服务器都以HTTP/1.1为基准,那直接采用Cache-Control:no-cache指定缓存的处理方式最为理想。但要整体掌握全部中间服务器使用的HTTP协议版本却是不现实的。因此,发送的请求会同时含有下面的两个首部字段:
Cache-Control:no-cache
Pragma:no-cache
五,Trailer
首部字段Trailer会事先说明在报文主体后记录了哪些首部字段。
该首部字段可应用在HTTP/1.1版本分块传输编码时:
HTTP/1.1 200 OK
Date: Tue, 03 Jul 2012 04:40:56 GMT
Content-Type: text/html
...
Transfer-Encoding: chunked
Trailer: Expires
...(报文主体)...
0
Expires:Tue, 28 Sep 2004 23:59:59 GMT
如上所示,指定首部字段Trailer的值为Expires,在报文主体之后出现了首部字段Expires。
六,Transfer-Encoding
该首部字段Transfer-Encoding规定了传输报文主体时采用的编码方式。(HTTP/1.1 的传输编码方式仅对分块传输编码有效)
举例:
HTTP/1.1 200 OK
Date:Tue, 03 Jul 2012 04:40:56 GMT
Cache-Control: public, max-age=604800
Content-Type: text/javascript; charset=utf-8
Expires: Tue,10 Jul 2012 04:40:56 GMT
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Content-Encoding: gzip
Transfer-Encoding: chunked
Connection: keep-alive
cfo <-16进制(十进制为3312)
...3312字节分块数据...
392 <-16进制(10进制为914)
...914字节分块数据...
0
以上用例中,正如首部字段Transfer-Encoding中指定的那样,有效使用分块传输编码,且被分为3312字节和914字节大小的分块数据。
七,Upgrade
首部字段Upgrade用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
举例:
请求报文:
GET /index.htm HTTP/1.1
Upgrade: TLS/1.0
Connection: Upgrade
响应报文:
HTTP/1.1 101 Switching Protocols
Upgrade: TLS/1.0, HTTP/1.1
Connction: Upgrade
上例中请求报文中Upgrade指定的值是 TLS/1.0,表示客户端向服务器询问是否支持TLS/1.0协议;而服务器端Upgrade指定的值为TLS/1.0, HTTP/1.1表明服务器支持TLS/1.0和HTTP/1.1。
因为Upgrade是Hop-by-hop首部,仅作用与客户端和邻接服务器之间,所以Connection的值被指定为Upgrade。
八,Via
使用Via首部是为了追踪客户端与服务器之间的请求和响应报文的传输路径。也就是说,报文经过代理或网关时,会现在首部字段Via中附加该服务器的信息,然后再进行转发。
举例:
客户端:
GET / HTTP/1.1
代理服务器A:
GET / HTTP/1.1
Via: 1.0 gw.hackr.jp(Squid/3.1)
代理服务器B:
GET / HTTP/1.1
Via: 1.0 gw.hackr.jp(Squid/3.1),
1.1 al.example.com(squid/2.7)
由上例我们可以看出,代理服务器会往Via首部添加自身服务器的信息。在经过代理服务器A时,Via首部附加了1.0 gw.hackr.jp(Squid/3.1)这样的字符串值,其中1.0表示服务器A支持的HTTP协议版本。经过代理服务器B时也可以再附加一个Via首部。
*Via首部是为了追踪路径,所以经常会和TRACE方法(见2.3节)一起使用。当代理服务器收到Max-Forwards:0时,不能再继续转发请求,需要把请求返回给客户端,代理服务器会将自身的信息附加到Via首部后,返回该请求的响应。
九,Warning
该首部通常会告知用户一些与缓存相关的问题的警告。
Warning首部的格式如下:
Warning: [警告码][警告的主机:端口号]"[警告内容]"([日期时间]) 最后的日期时间可以省略
举例:
Warning:113 gw.hackr.jp:8080 "Heuristic expiration" Tue, 03 Jul 2012 05:09:44 GMT
HTTP/1.1中定义了7种警告,如下表所示:
(警告内容仅供参考)