对于 http 的请求返回结果要进行内容的长度校验主要有两种方式,二者互斥使用
1. 客户端在 http 头 (head) 加 Connection:keep-alive 时,服务器的 response 是 Transfer-Encoding:chunked 的形式,通知页面数据是否接收完毕,例如长连接或者程序运行中可以动态的输出内容,例如一些运算比较复杂且需要用户及时的得到最新结果,那就采用 chunked 编码将内容分块输出.
2. 除了如 1 所述之外的情况一般都是可以获取到 Content-Length 的.
在 HTTP 协议中,Content-Length 用于描述 HTTP 消息实体的传输长度 the transfer-length of the message-body.在 HTTP 协议中,消息实体长度和消息实体的传输长度是有区别,比如说 gzip 压缩下,消息实体长度是压缩前的长度,消息实体的传输长度是 gzip 压缩后的长度.
在具体的 HTTP 交互中,客户端是如何获取消息长度的呢,主要基于以下几个规则:
响应为 1xx,204,304 相应或者 head 请求,则直接忽视掉消息实体内容.
如果有 Transfer-Encoding,则优先采用 Transfer-Encoding 里面的方法来找到对应的长度.比如说 Chunked 模式.
"如果 head 中有 Content-Length,那么这个 Content-Length 既表示实体长度,又表示传输长度.如果实体长度和传输长度不相等 (比如说设置了 Transfer-Encoding),那么则不能设置 Content-Length.如果设置了 Transfer-Encoding,那么 Content-Length 将被忽视 ".这句话翻译的优点饶,其实关键就一点:有了 Transfer-Encoding,则不能有 Content-Length.
Range 传输.不关注,没详细看了:)
通过服务器关闭连接能确定消息的传输长度.(请求端不能通过关闭连接来指明请求消息体的结束,因为这样可以让服务器没有机会继续给予响应).这种情况主要对应为短连接,即非 keep-alive 模式.
HTTP1.1 必须支持 chunk 模式.因为当不确定消息长度的时候,可以通过 chunk 机制来处理这种情况.
在包含消息内容的 header 中,如果有 content-length 字段,那么该字段对应的值必须完全和消息主题里面的长度匹配.
"The entity-length of a message is the length of the message-body before any transfer-codings have been applied"
也就是有 chunk 就不能有 content-length .
其实后面几条几乎可以忽视,简单总结后如下:
1,Content-Length 如果存在并且有效的话,则必须和消息内容的传输长度完全一致.(经过测试,如果过短则会截断,过长则会导致超时.)
2,如果存在 Transfer-Encoding(重点是 chunked),则在 header 中不能有 Content-Length,有也会被忽视.
3,如果采用短连接,则直接可以通过服务器关闭连接来确定消息的传输长度.(这个很容易懂)
结合 HTTP 协议其他的特点,比如说 Http1.1 之前的不支持 keep alive.那么可以得出以下结论:
1,在 Http 1.0 及之前版本中,content-length 字段可有可无.
2,在 http1.1 及之后版本.如果是 keep alive,则 content-length 和 chunk 必然是二选一.若是非 keep alive,则和 http1.0 一样.content-length 可有可无
我总结我的例子 如果 要是 js CSS html 这样的文件的话 会返回 contengt-length 字节 前提是 nginx 里的 gzip off 如果是 on 的话 返回 chunk
执行的如果是 动态 脚本的话, 还是返回 chunk 前提是 content:keep-alive 如果不是长连接的话 返回的头里面没有 content-leght ()
来源: https://www.2cto.com/kf/201801/710940.html