介绍
上一篇博文着重介绍了Cache-Control ,这篇博文将会介绍剩余的:
Connection Date Transfer-Enconding Trailer Upgrade Via Warning
1. Connection
Connection 头信息有2个作用,分别是:
- 控制不再转发给代理服务器的头信息
- 管理持久连接
(1).控制不再转发的头信息
Connection:逐跳首部
什么是逐跳首部?参见:这可能是最全的Http头信息资料了
例如:客户端发送给代理服务器的中头信息中是
GET / HTTP/1.1
Connection:Upgrade
Upgrade:HTTP/1.1
Cache-Control:no-cache
那么代理服务器发送给下一个服务器(可能是代理,也可能是最终服务器)的头信息中就会将Upgrade 头信息删除,变成
GET / HTTP/1.1
Cache-Control:no-cache
(2).管理持久连接
Connection:close
Connection:Keep-Alive
在HTTP 1.1 版本中,所有的连接默认都是持久连接
持久连接:进行一次Http通讯后,不断开TCP连接
当明确想断开连接时使用Connection:close 在HTTP 1.1 之前的版本中,默认都是非持久连接,因此如果要保持持久连接需要指定Connection:Keep-Alive
2.Date
Date 指明了创建Http 报文的时间 使用的格式有:
Date:Sun, 17 Oct 2021 15:08:00 GMT
Date:Sun, 17-Oct-21 15:08:00 GMT
Date:Sun Oct 17 15:08:00 2021
3.Transfer-Enconding
该头信息规定了传输报文主体是采用的编码方式。注意和Content-Encoding 区分。
-
Transfer-Enconding :在传输过程中使用的编码方式,仅用于两个节点之间的传递,而不是资源本身 [1]。 例如:源服务器采用了`gzip`传送给了代理服务器,代理服务器解析数据后,将传输方式更改为`chunked`分块传输给客户端
-
Content-Encoding :报文主体采用什么方式编码,整个传输过程中都不会更改
Transfer-Enconding:chunked
Transfer-Encoding: compress
Transfer-Encoding: deflate
Transfer-Encoding: gzip
Transfer-Encoding: identity
分块传输会将实体分成多个部分,每一块都会用十六进制来标记块的大小,而实体的最后一块会使用0(CR+LF) 来标记。
对于非持久连接,浏览器可以通过连接是否关闭来界定请求或响应实体的边界;而对于持久连接,这种方法显然不奏效,尽管已经发送完所有数据,但浏览器并不知道这一点,它无法得知这个打开的连接上是否还会有新数据进来,只能傻傻地等 要解决上面这个问题,最容易想到的办法就是计算实体长度,并通过头部告诉对方。这就要用到 Content-Length 了 由于 Content-Length 字段必须真实反映实体长度,但实际应用中,有些时候实体长度并没那么好获得,例如实体来自于网络文件,或者由动态语言生成。这时候要想准确获取长度,只能开一个足够大的 buffer,等内容全部生成好再计算。但这样做一方面需要更大的内存开销,另一方面也会让客户端等更久。 Transfer-Encoding 正是用来解决上面这个问题的。历史上 Transfer-Encoding 可以有多种取值,为此还引入了一个名为 TE 的头部用来协商采用何种传输编码。但是最新的 HTTP 规范里,只定义了一种传输编码:分块编码(chunked)。 分块编码相当简单,在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,报文中的实体需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的 CRLF(\r\n) ,也不包括分块数据结尾的 CRLF 。最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束 [2]
例子:
HTTP/1.1 200 OK
...
Content-Encoding:gzip
Transfer-Econding:chunked
...
cf0
...
392
...
0
4. Trailer
Trailer:Date
该指令指示在报文主体之后还有哪些头信息,不可以包含以下头信息 [3]:
- 用于信息分帧的首部 (例如
Transfer-Encoding 和 Content-Length ) - 用于路由用途的首部 (例如
Host ) - 请求修饰首部 (例如控制类和条件类的,如
Cache-Control ,Max-Forwards ,或者 TE ) - 身份验证首部 (例如
Authorization 或者 Set-Cookie ) Content-Encoding , Content-Type , Content-Range ,以及 Trailer 自身
可应用于分块传输编码,如:
HTTP/1.1 200 OK
...
Content-Encoding:gzip
Transfer-Econding:chunked
Trailer:Date
...
cf0
...
392
...
0
Date:Sun Oct 17 15:08:00 2021
为什么还需要这个字段?直接把头信息放到前面不就好了吗?
这时因为有些信息只有处理完实体内容后才知道。比如一个字节流的大小、消息的完整性验证,消息经过处理后的最终状态等。这时,就需要是使用`Trailer`将信息加到实体的后面
5.Upgrade
询问下一个直连服务器,是否可以使用其他的协议进行通信
Upgrade:TLS/1.0,webSocket
为什么使用`Upgrade`的时候,要配合`Connection:Upgrade`一起使用?
再回到HTTP 1.1的Connection头部,这儿有一个兼容性问题:我们以Upgrade头部为例,某个proxy实现了HTTP 1.0协议,将Upgrade原样转发给后端,后端和proxy升级协议,但是这个情况下,proxy不认识升级后的协议啊 [4]。
如果服务器决定升级这个连接,会返回 101 Switching Protocols 状态码,和要切换的协议,如: 客户端发起请求
GET / HTTP/1.1
...
Connection:Upgrade
Upgrade:TLS/1.0,webSocket
...
服务器给与回应
HTTP/1.1 101 Switching Protocols
...
Upgrade:TLS/1.0
...
如果不能使用其他协议,会返回常规的响应,例如:200 OK 注意: 由HTTP/1.1请求建立的连接可以升级为HTTP/2协议的连接,但是反过来不可以。事实上HTTP/2已经不再支持101状态码了,也不再支持任何连接升级机制。[5]
6.Via
Via: 1.0 p1.example.com, 1.1 p2.example.net
这个首部由代理服务器添加,每经过一个代理服务器,代理服务器会在Via 后面添加一条信息。可以用来追踪消息转发情况
7. Warning
HTTP/1.1 的Warning 首部是从HTTP/1.0 的响应首部Retry-After 演变过来的。该首部通常会告知用户一些与缓存相关的问题的警告。 Warning 的格式如下:
Warning: <警告码> <警告的主机:端口号> "<警告内容>" [<警告时间>]
(1). 警告码[6]
1XX :警告码描述了关于当前响应的新鲜度或者验证状态的警告信息,并且将会在验证之后被缓存服务器删除。2XX :警告码描述了验证之后不会被修复的某些展现内容方面的警告信息,并且在验证之后不会被缓存服务器删除。
7种警告码
警告码 | 文字描述 | 详细说明 |
---|
110 | Response is stale (响应已过期) | 代理返回的资源已过期 | 111 | Revalidate failed (再验证失败) | 代理再验证资源有效性时失败 | 112 | Disconnected Operation(断开链接操作) | 代理无法连接互联网 | 113 | Heuristic Expiration(试探性过期) | 响应的使用期超过24小时 (有效缓存的设定时间为24小时的情况下) | 199 | Miscellaneous Warning (杂项警告) | 任意的警告内容 | 214 | Transformation Applied(使用了转换) | 代理返回的展现内容进行了某些处理,比如改变了内容编码、媒体类型等。 | 299 | Miscellaneous Warning | 与199类似,只不过指代的是持久化警告。 |
Reference
[1]. Transfer-Encoding [2]. HTTP 协议中的 Transfer-Encoding [3]. Trailer [4]. 为什么HTTP Upgrade的时候,需要Connection: upgrade [5]. 协议升级机制 [6]. Warning
|