HTTP要确保它承载的“货物”知足如下条件:html
1、报文是箱子,实体是货物算法
若是把HTTP报文想象成因特网货运系统中的箱子,那么HTTP实体就是报文中实际的货物。浏览器
HTTP实体首部描述了HTTP报文的内容。HTTP/1.1版定义了如下10个基本字体首部字段。缓存
1 实体主体安全
首部字段以一个空白的CRLF行结束,随后就是实体主体的原始内容。服务器
2、Content-Length:实体的大小网络
Content-Length首部指示出报文中实体主体的字节大小。这个大小是包含了全部内容编码的,好比,对文本文件进行了gzip压缩的话,Content-Length首部就是压缩后的大小,而不是原始大小。架构
除非使用了分块编码,不然Content-Length首部就是带有实体主体的报文必须使用的。使用Content-Length首部是为了可以检测出服务器崩溃而致使的报文截尾,并对共享持久链接的多个报文进行正确分段。并发
1 检测截尾post
HTTP的早期版本采用关闭链接的办法来划定报文的结束。可是,没有Content-Length的话,客户端没法区分究竟是报文结束时正常的链接关闭,仍是报文传输中因为服务器崩溃而致使的链接关闭。客户端须要经过Content-Length来检测报文截尾。
报文截尾的问题对缓存代理服务器来讲尤为严重。若是缓存服务器收到被截尾的报文却没有识别出截尾的话,它可能会存储不完整的内容并屡次使用它来提供服务。缓存代理服务器一般不会为没有显示Content-Length首部的HTTP主体作缓存,以此减小缓存已截尾报文的风险。
2 Content-Length与持久链接
Content-Length首部对于持久链接是必不可少的。若是响应经过持久链接传送,就可能有另外一条HTTP响应紧随其后。客户端经过Content-Length首部就能够知道报文在何处结束,下一条报文从何处开始。
3 内容编码
Content-Length首部说明的是编码后(encoded)的主体的字节长度,而不是未编码的原始主体的长度。
4 肯定实体主体长度的规则
3、实体摘要
服务器使用Content-MD5首部发送对实体主体运行MD5算法的结果。只有产生响应的原始服务器能够计算并发送Content-MD5首部。中间代理和缓存不该当修改或添加这个首部,不然就会与验证端到端完整性的这个最终目的相冲突。Content-MD5首部是在对内容作了全部须要的内容编码以后,尚未作任何传输编码以前,计算出来的。为了验证报文的完整性,客户端必须先进行传输编码的解码,而后计算所获得的未进行传输编码的实体主体的MD5。
4、媒体类型和字符集
Content-Type首部字段说明了实体主体的MIME类型。MIME类型是标准化的名字,用以说明做为货物运载实体的基本媒体类型。客户端应用程序使用MIME类型来解释和处理其内容。
1 文本的字符编码
Content-Type: text/html; charset=iso-8859-4
2 多部分媒体类型
MIME中的multipart(多部分)电子邮件报文中包含多个报文,它们合在一块儿做为单一的复杂报文发送。每一部分都是独立的,有各自的描述其内容的集;不一样的部分之间用分界字符串链接在一块儿。
3 多部分表格提交
HTTP使用Content-Type:multipart/form-data或Content-Type:multipart/mixed这样的首部以及多部分主体来发送这种请求,举例以下:
Content-Type: multipart/form-data; boundary=[abcdefghijklmnopqrstuvwxyz]
其中的boundary参数说明了分割主体中不一样部分所用的字符串。
<FORM action="http://server.com/cgi/handle" enctype="multipart/form-data" method="post"> <P> What is your name?<INPUT type="text" name="submit-name"><BR> What files are you sending?<INPUT type="file" name="files"><BR> <INPUT type="submit" value="Send"><INPUT type="reset"> </FORM>
用户代理可能会发回下面这样的数据:
Content-Type: multipart/form-data; boundary=AaB03x --AzBo3x Content-Dispositon: form-data; name="submit-name" Sally --AaB03x Content-Disposition: form-data; name="files" Content-Type: multipart/mixed; boundary=BbC04y --BbC04y Content-Disposition: file; filename="essayfile.txt" Content-Type: text/plain --BbC04y Content-Disposition: file; filename="imagefile.gif" Content-Type: image/gif ...contents of imagefile.gif... --BbC04y --AaB03x--
4 多部分范围响应
HTTP对范围请求的响应也能够是多部分的。这样的响应中有Content-Type: mltipart/byterange首部和带有不一样范围的多部分主体。
5、内容编码
HTTP应用程序有时在发送以前须要对内容进行编码。
1 内容编码过程
2 内容编码类型
HTTP定义了一些标准的内容编码类型,并容许用扩展编码的形式增添更多的编码。Content-Encoding首部就用这些标准化的代号来讲明编码时使用的算法。
3 Accept-Encoding首部
为了不服务器使用客户端不支持的编码方式,客户端就把本身支持的内容编码方式列表放在请求的Accept-Encoding首部里发出去。若是HTTP请求中没有包含Accept-Encoding首部,服务器端就能够假设客户端可以接收任何编码方式。
6、传输编码和分块编码
传输编码也是做用在实体主体上的可逆变换,但使用它们时因为架构方面的缘由,同内容的格式无关。使用传输编码是为了改变报文中的数据在网络上传输的方式。
1 可靠传输
在HTTP中,只有少数一些状况下,所传输的报文主体可能会引起问题。其中两种状况以下所述。
1)未知的尺寸
若是不先生成内容,某些网关应用程序和内容编码器就没法肯定报文主体的最终大小。一般,这些服务器但愿在知道大小以前就开始传输数据。由于HTTP协议要求Content-Length首部必须在数据以前,有些服务器就是用传输编码来发送数据,并用特别的结束脚注代表数据结束。
2)安全性
你能够用传输编码来把报文内容扰乱,而后再共享的传输网络上发送。不过,因为像SSL这样的传输层安全体系的流行,就不多须要靠传输编码来实现安全性了。
2 Transfer-Encoding首部
HTTP协议中只定义了下面两个首部来描述和控制传输编码。
下面的例子中,请求使用了TE首部来告诉服务器它能够接收分块编码(若是是HTTP/1.1应用程序的话,这就是必须的)而且愿意接受附在分块编码的报文结尾上的拖挂:
GET /new_products.html HTTP/1.1 Host: www.joes-hardware.com User-Agent: Mozilla/4.61 [en] (WinNT; I) TE: trailers, chunked ...
对它的相应中包含Trasfer-Encoding首部,用于告诉接收方已经用分块编码对报文进行了传输编码:
HTTP/1.1 200 OK Transfer-Encoding: chunked Server: Apache/3.0 ...
在这个起始首部以后,报文的结构就将发生改变。
传输编码的值都是大小写无关的。HTTP/1.1规定在TE首部和Transfer-Encoding首部中使用传输编码值。最新的HTTP规范只定义了一种传输编码,就是分块编码。
3 分块编码
分块编码把报文分割为若干个大小已知的块。块之间是紧挨着发送的,这样就不须要在发送以前知道整个报文的大小。
7、验证码和新鲜度
1 新鲜度
服务器能够用这两个首部之一来提供这种信息:Expires(过时)和Cache-Control(缓存控制)。
Expires首部规定文档“过时”的具体时间——此后就不该当认为它仍是最新的。Expires首部的语法以下:
Expires: Sun Mar 18 23:59:59 GMT 2001
客户端和服务器为了能正确使用Expires首部,它们的始终必须同步。
Cache-Control首部能够用秒数来规定文档最长使用期——从文档离开服务器以后算起的总计时间。使用期不与时钟同步,所以能够给出更精确的结果。
2 有条件的请求与验证码
当请求缓存服务器中的副本时,若是它再也不新鲜,缓存服务器就须要保证它有一个新鲜的副本。缓存服务器能够向原始服务器获取当前的副本。但在不少状况下,原始服务器上的文档仍然与缓存中已过时的副本相同。若是服务器上的文档和已过时的缓存副本相同,而缓存服务器仍是要从原始服务器上取文档的话,那缓存服务器就是在浪费网络带宽,给缓存服务器和原始服务器增长没必要要的负载,是全部的事情都变慢了。
为了不这种状况,HTTP为客户端提供了一种方法,仅当资源改变时才请求副本,这种特殊请求称为有条件的请求。有条件的请求是标准的HTTP请求报文,但仅当某个特定条件为真时才执行。
GET /announce.html HTTP/1.0 If-Modified-Since: Sat, 29 Jun 2002, 14:30:00 GMT
有条件的请求是经过以“If-”开头的有条件的首部来实现的。
归纳一下,当客户端屡次访问同一个资源时,首先须要判断它当前的副本是否是仍然新鲜。若是再也不新鲜,它们就必须从服务器获取最新的版本。为了不在资源没有改变的状况下收到一份相同的副本,客户端能够向服务器发送有条件的请求,说明能惟一标识客户端当前副本的验证码。只在资源和客户端的副本不一样的状况下服务器才会发送其副本。