HTTP Transfer-Encoding:chunk

732 阅读2分钟

在HTTP1.1版本中,因为tcp三次握手导致的性能问题,因此使用Connection: keep-alive来保持长链接。浏览器通过Content-Length来判断数据是否接受完毕来判断是否渲染内容。客户端可以通过头部字段Connection:close来禁止长链接。

如果没有Content-Length这个字段,那么请求将会是一直pengding的状态。如果Content-Length定义的长度与实际的数据长度不一致,会导致数据的截断或者pengding状态。

Transfer-Enconding:chunk 分块编码规则:

  1. 每个分块包含两个部分,长度头和数据块;

  2. 长度头是以 CRLF(回车换行,即\r\n)结尾的一行明文,用 16 进制数字表示长度;

  3. 数据块紧跟在长度头后,最后也用 CRLF 结尾,但数据不包含 CRLF;

  4. 最后用一个长度为 0 的块表示结束,即“0\r\n\r\n”。

image.png

image.png 通过设置这个头部浏览器就可以正确的解析数据,并逐行的显示了。

范围请求

范围请求不是WEB服务器的必备功能,可以实现也可以不实现。所有服务器必须在头部字段添加Accept-Ranges:bytes明确告诉客户端支持范围请求。如果不不支持可以添加头部字段Accept-Ranges:none或者不返回这个头部字段。

单一范围

GET /z4d4kWk.jpg HTTP/1.1
Host: i.imgur.com
Range: bytes=0-1023

服务器会返回206的状态码 partial content

HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/146515
Content-Length: 1024
...
(binary content)

多重范围请求

GET /z4d4kWk.jpg HTTP/1.1
Host: i.imgur.com
Range: bytes=0-50, 100-150

服务器返回206 Partial Content状态码和Content-Type:multipart/byteranges; boundary=3d6b6a416f9b5头部,Content-Type:multipart/byteranges表示这个响应有多个byterange。每一部分byterange都有他自己的Centen-type头部和Content-Range,并且使用boundary参数对body进行划分

HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
Content-Length: 282 --3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 0-50/1270

<html> <head> <title>Example Do
--3d6b6a416f9b5
Content-Type: text/html Content-Range: bytes 100-150/1270
eta http-equiv="Content-type" content="text/html; c
--3d6b6a416f9b5--

条件范围请求

参照MDN

服务器收到Range字段后,需要做的事情

1. 必须检查范围是否合法,如果不合法则返回416状态码,表示无法处理
2. 如果范围正确则会去读取文件判断,返回206 Partial Content
3. 返回Content-Range头部