Transfer-Encoding、Content-Length、Content-Encoding、Accept-Encoding

1.概述

我们在日常进行HTTP请求的时候,会遇到请求头或者响应头中有Transfer-Encoding、Content-Length、Content-Encoding、Accept-Encoding这几个,难免会不知道各自的含义及使用场景,也可能会搞混,我们今天就简单的捋一下这几个Header。

2.keep-alive

在讲解上面几个头之前,我们必须先了解一下Persistent Connection(持久连接或者长连接),HTTP持久连接这个机制,很大程度上提高了HTTP的性能,我们看下在引入持久连接之前,HTTP连接是什么样子:

先进行TCP握手,然后进行数据传输,完成数据传输之后,释放连接。当网络内容复杂时候,会出现多次数据传输,那么就会造成多次频繁的创建Socket和释放,频繁的握手,就会出现延时,这个问题在引入持久连接得意解决。

通过设置设置 Connection头部为keep-alive实现持久连接:

keepalive connections机制可以在数据传输完成之后仍然保持TCP连接,以备后用,当用户需要再次获取数据时,直接使用刚刚空闲下来的连接,无需再次握手,这样就解决了延时问题,提高了HTTP的性能。持久连接时HTTP1.0后来才引进的,到了HTTP1.1规定所有连接都必须是持久的,在Header上添加了Connection为close。在现代浏览器中,一般同时开启6~8个keepalive connections的socket连接,并保持一定的链路生命,当不需要时再关闭;而在服务器中,一般是由软件根据负载情况进行配置。

3.主要内容

3.1.Content-Length

我们通过给HTTP请求添加Content-Length头部表示请求体的实际长度,也可以由服务器端添加Content-Length返回给客户端,表示响应体内容的实际长度。在实际应用中,Content-Length有时候不好获取,比如实体来自于网络文件或者是有数据库动态产生的,就很难获取它的准确长度。这时候倒是可以开一个足够大的buffer,等内容全部生成完毕在准确计算buffer的总长度,然而这样会导致内存消耗太大,也会让客户端等待时间过长。

当HTTP请求时短连接的时候,数据传输完成会根据连接是否关闭判断请求体或者响应体的边界,所以不需要标明请求体或者响应体的实际长度,请求就可以顺利完成;而当HTTP为长连接的时候,很显然不可以,必须要拥有判断请求或者响应体的边界,才能完成网络请求,如果Content-Length的值小于实际长度,则数据将会被截断,如果Content-Length的值大于实际长度则会导致网络请求处于停滞状态;如果没有Content-Length或者其他可以判定实体边界,则网络请求还是会被停滞。

3.2.Transfer-Encoding

使用Transfer-Encoding可以解决我们上面所提到的问题,Transfer-Encoding可以代替Content-Length。Transfer-Encoding表示传输编码,之前文当中给它定义了gzip/compress/deflate/identity/chunked等几种不区分大小写的多种取值,在最新的文档中传输编码之定义了一种编码值:chunked(分块编码)。当我们给请求或者响应的头部添加了Transfer-Encoding:chunked的时候,表示实体在传输的过程中采用的是分块编码的方式,实体被改为一系列的分块,每一个部分分块上面都有数据内容和长度,当分块内容为空长度为0时,意味着实体的边界,数据传输结束。所以,在HTTP网络请求中,如果无法确定实体的Content-Length的大小或者没有添加Content-Length作为头部信息的一部分,会导致网络请求发生问题,此时添加头Transfer-Encoding:chunked(分块编码)可以解决长度问题。

3.3.Accept-Encoding和Content-Encoding

Accept-Encoding添加在请求头中,向服务器端表明客户端支持的编码格式,Content-Encoding存在于响应头中,由服务器端返回,表示响应体内容的编码格式,常见的编码格式有gzip/compress/deflate/identity。可以结合Transfer-Encoding使用。

4.举例说明

再一次HTTP长连接中,无法判断请求体的长度和响应体的长度,我们就会做如下的流程:

  1. 客户端将请求内容加入到请求体中,添加请求头Transfer-Encoding:chunked表明分块编码,同时添加Accept-Encoding:gzip表明客户端支持gzip的编码格式;
  2. 服务器端接收到客户端的网络请求,根据客户端传来的Transfer-Encoding:chunked可知请求体位分块编码,紧接着开始接收请求体数据,当接收到的分块的内容为空长度为0时,说明到了请求体的边界,服务器端完成了数据接收。
  3. 经过一系列的操作,服务器端完了业务处理,给客户端返回数据,由于要返回的数据长度无法获取到,所以服务器端在返回数据中添加了头Transfer-Encoding:chunked表明分块编码,然后将每一块数据内容采用gzip进行编码,同时添加Content-Encoding:gzip表明服务器对返回的数据采用了gzip编码。
  4. 客户端收到服务器端的响应,因为响应头包含了Transfer-Encoding:chunked,所以一直到响应数据的分块长度为0内容为空,才算是数据传输完成,此时客户端会解析服务端发来的Content-Encoding:gzip,并且采用gzip方法解码数据,完成一次数据请求。

对于HTTP请求,我掌握的不是那么精,所以大概能讲出这么多,希望各位大神多多批评指正。

 

 

 

 

 

 

 

 

 

 

accept-ranges是HTTP协议中的一个响应头部,用于指示服务器是否支持分块传输(chunked transfer encoding)和范围请求(range requests)。 在HTTP/1.1协议中,范围请求允许客户端请求部分资源的内容,而不是整个资源。例如,如果一个大的视频文件被分成多个部分,一个客户端可以只请求其中的一个部分而不是整个文件。支持范围请求可以提高性能和降低网络带宽的消耗。 accept-ranges头部的值可以是"none"、"bytes"或其他自定义值。当值为"none"时,表示服务器不支持范围请求。当值为"bytes"时,表示服务器支持范围请求,并且只接受字节范围请求。其他自定义值可以用于指示服务器支持其他类型的范围请求,但这种情况比较少见。 例如,一个支持范围请求的响应头部可以如下所示: HTTP/1.1 200 OK Accept-Ranges: bytes Content-Length: 1024 在这个响应中,Accept-Ranges头部的值为"bytes",表示服务器支持字节范围请求。Content-Length头部指示响应正文的总长度为1024个字节。如果客户端想要请求其中的一部分,可以使用Range头部来指定范围,例如: Range: bytes=0-511 这个请求表示客户端只需要请求响应正文的前512个字节。服务器将返回一个206 Partial Content响应,并在Content-Range头部中指定返回的内容范围,例如: HTTP/1.1 206 Partial Content Accept-Ranges: bytes Content-Length: 512 Content-Range: bytes 0-511/1024 在这个响应中,Content-Range头部指示返回的内容范围是0到511字节,总共有1024个字节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值