今天面试遇到一个问题,HTTP协议中 content-length与chunk的区别
以前学习Ajax的时候遇到过content-length的用法,但是chunk以前只是有点印象,今晚特地来了解一波。
Content-Length 参考链接:http://www.kafan.cn/edu/45992664.html
1、content-length是啥?
content-length是消息传输实体的传输长度。要注意,消息的长度和传输长度是不一样的概念。因为,消息是有可能经过压缩或其它处理的。如果Transfer-Encoding里设置了chunk模式,那么则忽略content -length。
2、一定要有content-length?
这个要分情况。
在HTTP/1.0下,content-length可有可无。因为通过服务器端关闭连接可以确定消息的传输长度,谓之短连接,即非keep-live模式
在HTTP/1.1下,如果设置了transfer-Encoding,说明消息长度和消息传输长度不等,此时不能设置content-length,有也会被忽视。如果没有设置transfer-Encoding,那么情况就和HTTP1.0一样,可以是非Keep-live模式,也可以设置Content-length。
Chunk 参考链接:
http://blog.csdn.net/xifeijian/article/details/42921827
https://www.zhihu.com/question/26495136
https://tools.ietf.org/html/rfc2616#section-3.6.1
Transfer-Encoding下Chunk模式是在HTTP/1.1才有的模式,顾名思义,即分块传输。
1、那么为什么会分块传输呢?
如果服务器准备发送的内容需要动态创建,那么在创建完成之前,消息大小都是未知的,那么消息头就无法生成。而Chunk模式允许消息头在传输完成之发送,这就可以在消息大小生成前发送消息内容。如果没有这种模式,会造成浏览器端迟迟收不到响应,因为服务器处于动态创建内容的缓冲状态。
那么,分块又是干嘛的呢。如果消息需要进行压缩的话,那么就可以压缩与传输并行,也就是说,压缩一块消息,传输一块一块消息,边压缩,边传输,这样可以提高传输效率。
2、分块格式
见下图(来自https://tools.ietf.org/html/rfc2616#section-3.6.1)
Chunked-Body = *chunk
last-chunk
trailer
CRLF
chunk = chunk-size [ chunk-extension ] CRLF
chunk-data CRLF
chunk-size = 1*HEX
last-chunk = 1*("0") [ chunk-extension ] CRLF
chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)
trailer = *(entity-header CRLF)
格式如上,
简单说明一下,主要有三个大部分:
首先,Chunk每一个非空的部分有俩个部分组成:
1、chunk-size及其长度单位
2、chunk-data
其次,Chunk串的最后一块是一个长度为0的块(last-chunk)
最后,Chunk最后一块的后面跟着一个可选的尾部trail(包括消息头header)
CRLF是指回车换行