HTTP 首部
1. HTTP 报文首部
HTTP 协议的请求和响应报文中必定包含 HTTP 首部,首部内容为客户端和服务器分别处理请求和响应提供所需要的信息
报文首部构成
-
HTTP 请求报文
在请求中,HTTP 报文由方法、URI、HTTP 版本、HTTP 首部字段等部分构成
示例:访问 http://hackr.jp,请求报文的首部信息
GET / HTTP/1.1 Host: hackr.jp User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*; q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Connection: keep-alive If-Modified-Since: Fri, 31 Aug 2007 02:02:20 GMT If-None-Match: "45bae1-16a-46d776ac" Cache-Control: max-age=0
-
HTTP 响应报文
在响应中,HTTP 报文由 HTTP 版本、状态码(数字和原因短语)、HTTP 首部字段 3 部分构成
示例:访问 http://hackr.jp,返回的响应报文首部信息
HTTP/1.1 304 Not Modified Date: Thu, 07 Jun 2012 07:21:36 GMT Server: Apache Connection: close Etag: "45bae1-16a-46d776ac"
HTTP 首部字段包含的信息最为丰富,首部字段同时存在于请求和响应报文内,并涵盖 HTTP 报文相关的内容信息
2. HTTP 首部字段
2.1 HTTP 首部字段传递重要信息
HTTP 首部字段是构成 HTTP 报文的要素之一。使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证消息等内容
2.2 HTTP 首部字段结构
HTTP 首部字段是由字段名和字段值构成,中间用 : 分割
首部字段名:字段值
示例:
Content-Type:text/html
字段值对应单个 HTTP 首部字段可以由多个值
Keep-Alive:timeout=15,max=100
2.3 4 种 HTTP 首部字段类型
HTTP 首部字段根据实际用途被分为以下四种类型
-
通用首部字段(General Header Fields)
请求报文和响应报文两方都会使用的首部
-
请求首部字段(Request Header Fields)
从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级信息
-
响应首部字段(Response Header Fields)
从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容、也会要求客户端附加额外的内容信息
-
实体首部字段(Entity Header Fields)
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息
2.4 HTTP 首部字段一览
HTTP/1.1 规范定义了如下 47 种首部字段
-
通用首部字段
首部字段名 说明 Cache-Control 控制缓存的行为 Connection 逐跳首部、连接的管理 Date 创建报文的日期时间 Pragma 报文指令 Trailer 报文末端的首部一览 Transfer-Encoding 指定报文主体的传输编码方式 Upgrade 升级为其他协议 Via 代理服务器的相关信息 Warning 错误通知 -
请求首部字段
首部字段名 说明 Accept 用户可处理的媒体类型 Accept-Charset 优先的字符集 Accept-Encoding 优先的内容编码 Accept-Language 优先的语言(自然语言) Authorization Web 认证信息 Expect 期待服务器的特定行为 From 用户的电子邮箱地址 Host 请求资源所在服务器 If-Match 比较实体标记 (ETag) If-Modified-Since 比较资源的更新时间 If-None-Match 比较实体标记(与 If-Match 相反) If-Range 资源未更新时发送实体 Byte 的范围请求 If-Unmodified-Since 比较资源的更新时间 (与 If-Unmodified-Since 相反) Max-Forwards 最大传输逐跳数 Proxy-Authorization 代理服务器要求客户端的认证消息 Range 实体的字节范围请求 Referer 对请求中 URI 的原始获取方 TE 传输编码的优先级 User-Agent HTTP 客户端程序的信息 -
响应首部字段
首部字段名 说明 Accept-Ranges 是否接受字节范围请求 Age 推算资源创建经过时间 ETag 资源的匹配信息 Location 令客户端重定向至指定 URI Proxy-Authenticate 代理服务器对客户端的认证信息 Retry-After 对再次发起请求的时机要求 Server HTTP 服务器的安装信息 Vary 代理服务器缓存的管理信息 WWW-Authenticate 服务器对客户端的认证信息 -
实体首部字段
首部字段名 说明 Allow 资源可支持的 HTTP 方法 Content-Encoding 实体主体适用的编码方式 Content-Language 实体主体的自然语言 Content-Length 实体主体的大小(单位:字节) Content-Location 替代对应资源的 URI Content-MD5 实体主体的报文摘要 Content-Range 实体主体的位置范围 Content-Type 实体主体的媒体类型 Expires 实体主体过期的日期时间 Last-Modified 资源的最后修改日期时间
2.5 非 HTTP/1.1 首部字段
如 Cookie、Set-Cookie 和 Content-Disposition 等在其他 RFC 种定义的首部字段
2.6 End-to-end 首部和 Hop-by-hop 首部
HTTP 首部字段将定义成缓存代理和非缓存代理的行为分成两种类型
-
端到端首部(End-to-end Header)
分在此类别中的首部会转发给请求/响应对应的最终接受目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发
-
逐跳首部(Hop-by-hop Header)
分在此类别的首部只对单次转发有效,会因通过缓存或代理而不再转发
HTTP/1.1 和之后版本中,如果要使用 hop-by-hop 首部,需提供 Connection 首部字段
HTTP/1.1 中的逐跳首部字段,如下所示:
Connection
Keep-Alive
Proxy-Authenticate
Proxy-Authorization
Trailer
TE
Transfer-Encoding
Upgrade
注: 除了这 8 个首部字段之外,其他所有字段都属于端到端首部
3. HTTP/1.1 通用首部字段
通用首部字段是指,请求和响应报文都会用到的首部
3.1 Cache-Control
通过指定首部字段 Cache-Control 的指令,就能操作缓存的工作机制
首部字段 Cache-Control 能够控制缓存的行为
指令的参数是可选的,多个指令之间通过 “,”分割,首部字段 Cache-Control 的指令可用于请求及响应时
Cache-Control:private,max-age=0,no-cache
可用的指令按请求和响应分类
-
缓存请求指令
指令 参数 说明 no-cache 无 强制向源服务器再次验证 no-store 无 不缓存请求或响应的任何内容 max-age = 「秒」 必需 响应的最大 Age 值 max-stale = 「秒」 可省略 接受已过期的响应 min-fresh = 「秒」 必需 期望在指定的时间内仍有效 no_transform 无 代理不可更改媒体类型 only-if-cached 无 从缓存获取资源 cache-extention - 新指令标记(token) -
缓存响应指令
指令 参数 说明 public 无 可向任意方提供响应的缓存 private 可省略 仅向特定用户返回响应 no-cache 可省略 缓存前必须先确认其有效性 no-store 无 不缓存请求或响应的任何内容 no-transform 无 代理不可更改媒体类型 must-revalidate 无 可缓存但必须再向源服务器确认 proxy-revalidate 无 要求中间缓存服务器对缓存的响应有效性再进行确认 max-age = 「秒」 必需 响应的最大 Age 值 s-maxage = 「秒」 必需 公共缓存服务器响应的最大 Age 值 cache-extension - 新指令标记(token)
表示是否能缓存的指令
-
public 指令
Cache-Control: public
当指定使用 public 指令时,则明确表明其它用户可利用缓存
-
private 指令
Cache-Control: private
当指定 private 指令后,响应只以特定的用户作为对象。缓存服务器会对该特定用户提供资源缓存的服务,对其他用户发送过来的请求,代理服务器则不会返回缓存
-
no-cache 指令
Cache-Control: no-cache
使用 no-cache 指令的目的是为了防止从缓存中返回过期的资源
客户端发送的请求中如果包含 no-cache 指令,表示客户端将不会再接受缓存过的响应
服务器返回的响应中包含 no-cache 指令,缓存服务器将不能对资源进行缓存
-
控制可执行缓存对象的指令
-
no-store 指令
Cache-Control: no-store
使用 no-store 指令,暗示请求或响应包含机密信息。该指令规定缓存不能在本地存储请求或响应的任一部分
-
-
指定缓存期限和认证的指令
-
s-maxage 指令
Cache-Control: s-maxage = 604800(单位:秒)
s-maxage 指令的功能和 max-age 的指令相同,不同点在于对于向同一用户重复返回响应的服务器来说,该指令没有任何作用,另外当使用 s-maxage 指令后,则直接忽略对 Expires 首部字段及 max-age 指令的处理
-
max-age 指令
Cache-Control: max-age = 604800(单位:秒)
当客户端发送的请求中包含 max-age 指令时,如果判断缓存资源的缓存时间数值比指定时间数值更小。那么客户端就接受缓存的资源
当指定 max-age = 0 时,缓存服务器需要将请求再转发给源服务器
当服务器返回响应中包含 max-age 指令时,缓存服务器将不对资源的有效性再做确认,而 max-age 数值代表资源保存为缓存的最长时间
-
min-fresh 指令
Cache-Control: min-fresh = 60(单位:秒)
min-fresh 指令要求缓存服务器返回至少还未超过指定时间的缓存资源
如:指定 min-fresh 为 60 秒后,过了 60 秒的资源都无法作为响应返回
-
max-stale 指令
Cache-Control: max-stale = 3600(单位:秒)
使用 max-stale 可指示缓存资源,即使过期也照常接受
-
only-if-cached 指令
Cache-Control: only-if-cached
使用 only-if-cached 指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回
该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性
-
must-revalidate 指令
Cache-Control: must-revalidate
使用 must-revalidate 指令,代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效
使用 must-revalidate 指令会忽略请求的 max-stale 指令
-
proxy-revalidate 指令
Cache-Control: proxy-revalidate
proxy-revalidate 指令要求所有的缓存服务器在接受到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性
-
no-transform 指令
Cache-Control: no-transform
使用 no-transform 指令规定无论是在请求还是响应中,缓存都不能改变实体主体的类型
-
-
Cache-Control 扩展
cache-extension token
Cache-Control: private,community="UCI"
通过 cache-extension 标记(token),可以扩展 Cache-Control 首部字段内的指令。如上例,Cache-Control 首部字段本身没有 community 这个指令,借助 extension tokens 实现了该指令的添加
extension tokens 仅对能理解它的缓存服务器来说有意义
3.2 Connection
Connection 首部字段具备如下两个作用
-
控制不再转发给代理的首部字段
Connection: 不再转发的首部字段名
在客户端发送请求和服务器返回响应内,使用 Connection 首部字段,可控制不再转发给代理的首部字段(即Hop-by-hop 首部)
-
管理持久连接
Connection: close
HTTP/1.1 版本默认连接都是持久连接,为此,客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 Close
3.3 Date
首部字段 Date 表明创建 HTTP 报文的日期和时间
HTTP/1.1 协议中日期时间的格式
Date: Tue, 03 Jul 2012 04:40:59 GMT
3.4 Pragma
Pragma 是 HTTP/1.1 之前版本的历史遗留字段,仅作为与 HTTP/1.0 的向后兼容而定义
Pragma: no-cache
只用在客户端发送的请求中,客户端会要求所有的中间服务器不返回缓存的资源
3.5 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
3.6 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
cf0 ←16进制(10进制为3312)
...3312字节分块数据...
392 ←16进制(10进制为914)
...914字节分块数据...
0
以上用例中,在首部字段 Transfer-Encoding 中指定的那样,有效使用分块传输编码,分别被分成 3312 字节和 914 字节大小的分块数据
3.7 Upgrade
首部字段 Upgrade 用于检测 HTTP 协议及其它协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议
使用首部字段 Upgrade ,还需要额外指定 Connection:upgrade
对应附有首部字段 Upgrade 的请求,服务器可用 101 Switching Protocols 状态码最为响应返回
3.8 Via
使用首部字段 Via 是为了追踪客户端与服务器直接的请求和响应报文的传输路径
首部字段 Via 不仅用于追踪报文的转发,还可避免请求回环的发生。所以必须在经过代理时附加该首部字段内容
3.9 Warning
该首部通常会告知用户一些与缓存相关的问题的警告
Warning: 113 gw.hackr.jp:8080 "Heuristic expiration" Tue, 03 Jul 2012
格式
Warning: [警告码][警告的主机:端口号]“[警告内容]”([日期时间])
HTTP/1.1 警告码
警告码 | 警告内容 | 说明 |
---|---|---|
110 | Response is stale(响应已过期) | 代理返回已过期的资源 |
111 | Revalidation failed(再验证失败) | 代理再验证资源有效性时失败(服务器无法到达等原因) |
112 | Disconnection operation(断开连接操作) | 代理与互联网连接被故意切断 |
113 | Heuristic expiration(试探性过期) | 响应的试用期超过 24 小时(有效缓存的设定时间大于 24 小时的情况下) |
199 | Miscellaneous warning(杂项警告) | 任意的警告内容 |
214 | Transformation applied(使用了转换) | 代理对内容编码或媒体类型等执行了某些处理 |
299 | Miscellaneous persistent warning(持久杂项警告) | 任意的警告内容 |