美文网首页
第三章:http报文

第三章:http报文

作者: 闫鹏飞写字的地方 | 来源:发表于2021-09-24 15:54 被阅读0次
    image.png image.png

    如果说HTTP是因特网的信使,那么HTTP报文就是它用来搬东西的包裹了。第
    1章说明了HTTP程序是怎样互相发送报文来完成工作的。本章则会介绍所有与
    HTTP报文有关的事情一如何 创建报文,以及如何理解它们。通过阅读本章,就
    可以了解编写自己的HTTP应用程序所需掌握的大部分内容。具体来说,你会理解
    下列概念:
    ●报文是如何流动的;
    ●HTTP报文的三个组成部分(起始行、首部和实体的主体部分) ;
    ●请求和响应报文之间的区别;
    ●请求报文支持的各种功能(方法)
    ●和响应报文-起返回的各种状态码;
    ●各种各样的HTTP首部都是用来做什么的。

    3.1
    报文流
    HTTP报文是在HTTP应用程序之间发送的数据块。这些数据块以一一些文本形式的
    元信息(meta-information) 开头,这些信息描述了报文的内容及含义, 后面跟着
    可选的数据部分。这些报文在客户端、服务器和代理之间流动。术语“流入”、“流
    出”、“上游”及“下游”都是用来描述报文方向的。

    3.1.1
    报文流入源端服务器
    HTTP使用术语流入(inbound) 和流出(outbound) 来描述事务处理(transaction)
    的方向。报文流入源端服务器,工作完成之后,会流回用户的Agent代理中(参见
    图3-1)。


    image.png

    3.1.2
    报文向下游流动
    HTTP报文会像河水一样流动。不管是请求报文还是响应报文,所有报文都会向
    下游(downstream) 流动(参见图3-2)。所有报文的发送者都在接收者的上游
    (upstream)。在图3-2中,对请求报文来说,代理1位于代理3的上游,但对响应;
    报文来说,它就位于代理3的下游。


    image.png

    3.2
    报文的组成部分
    HTTP报文是简单的格式化数据块。看一下图3-3给出的例子。每条报文都包含一
    条来自客户端的请求,或者一条来自服务器的响应。它们由三个部分组成:对报文
    进行描述的起始行(start line)、包含属性的首部(header) 块,以及可选的、包含
    数据的主体(body) 部分。


    image.png

    起始行和首部就是由行分隔的ASCII文本。每行都以一个由两个字符组成的行终止
    序列作为结束,其中包括一个回车符(ASCII 码13)和一一个换行符(ASCII 码10)。
    这个行终止序列可以写做CRLF。需要指出的是,尽管HTTP规范中说明应该用
    CRLF来表示行终止,但稳健的应用程序也应该接受单个换行符作为行的终止。有
    些老的,或不完整的HTTP应用程序并不总是既发送回车符,又发送换行符。
    实体的主体或报文的主体(或者就称为主体)是一个可选的数据块。与起始行和首
    部不同的是,主体中可以包含文本或二进制数据,也可以为空。
    在图3-3的例子中,首部给出了一些与主体有关的信息。Content -Type行说明了
    主体是什么一一在这 个例子中,就是纯文本文档。Content -Length行说明了主体
    有多大,在这里就只有19个字节。

    3.2.1
    报文的语法
    所有的HTTP报文都可以分为两类:请求报文(request message)和响应报文
    (response message)。 请求报文会向Web服务器请求-一个动作。响应报文会将请求
    的结果返回给客户端。请求和响应报文的基本报文结构相同。图3-4显示了获取一
    张GIF图片所需的请求和响应报文。

    image.png

    这是请求报文的格式:
    <method> <request -URL> <version>
    <headers>
    <entity-body>
    这是响应报文的格式(注意,只有起始行的语法有所不同) :
    <version> <statu8> <reason-phrase>
    <headers>
    <entity-body>
    下面是对各部分的简要描述。
    ●方法(method)
    客户端希望服务器对资源执行的动作。是一个单独的词,比如GET.HEAD或
    POST。本章稍后将详细介绍方法。
    ●请求URL (request-URL)
    命名了所请求资源,或者URL路径组件的完整URL。如果直接与服务器进行对
    话,只要URL的路径组件是资源的绝对路径,通常就不会有什么问题一-服务
    器可以假定自己是URL的主机/端口。第2章详细地介绍了URL的语法。
    ●版本(version)
    报文所使用的HTTP版本,其格式看起来是这样的:
    HTTP/ <major>. <minor>
    其中主要版本号(major) 和次要版本号(minor) 都是整数。本章稍后会详细说
    明HTTP的版本问题。
    ●状态码(status-code)
    这三位数字描述了请求过程中所发生的情况。每个状态码的第- -位数字都用于描
    述状态的一般类别(“成功”、 “出错”等)。本章稍后提供了HTTP规范定义的状
    态码及其含义的完整列表。

    ●原因短语(reason-phrase)
    数字状态码的可读版本,包含行终止序列之前的所有文本。本章稍后提供了
    HTTP规范定义的所有状态码的原因短语示例。原因短语只对人类有意义,因
    此,比如说,尽管响应行HTTP/1.0 200 NOT OK和HTTP/1.0 200 OK中原因短;
    语的含义不同,但同样都会被当作成功指示处理。

    ●首部(header)
    可以有零个或多个首部,每个首部都包含-一个名字, 后面跟着一个冒号(:), 然
    后是一个可选的空格,接着是一个值,最后是一个CRLF。首部是由一个空行
    (CRLF)结束的,表示了首部列表的结束和实体主体部分的开始。有些HTTP版
    本,比如HTTP/1.1,要求有效的请求或响应报文中必须包含特定的首部。本章
    稍后会探讨各种HTTP首部。
    ● 实体的主体部分(entity-body)
    实体的主体部分包含一个由任意数据组成的数据块。并不是所有的报文都包含实
    体的主体部分,有时,报文只是以-一个CRLF结束。第15章详述了实体。
    图3-5展示了一些假想的请求和响应报文。

    image.png

    3.2.2 起始行
    所有的HTTP报文都以-一个起始行作为开始。请求报文的起始行说明了要做些什么。
    响应报文的起始行说明发生了什么。
    1.请求行
    请求报文请求服务器对资源进行一些操作。请求报文的起始行,或称为请求行,包
    含了一个方法和-一个请求URL,这个方法描述了服务器应该执行的操作,请求URL
    描述了要对哪个资源执行这个方法。请求行中还包含HTTP的版本,用来告知服务
    器,客户端使用的是哪种HTTP。
    所有这些字段都由空格符分隔。在图3-5a中,请求方法为GET,请求URL为
    50|第3章
    /test/hi-there.txt,版本为HTTP/1.1。在HTTP/1.0之前,并不要求请求行中包含
    HTTP版本号。

    2.响应行
    响应报文承载了状态信息和操作产生的所有结果数据,将其返回给客户端。响应报
    文的起始行,或称为响应行,包含了响应报文使用的HTTP版本、数字状态码,以
    及描述操作状态的文本形式的原因短语。
    所有这些字段都由空格符进行分隔。在图3-5b中,HTTP版本为HTTP/1.0,状态
    码为200 (表示成功),原因短语为OK,表示文档已经被成功返回了。在HTTP/1.0
    之前,并不要求在响应中包含响应行。

    3.方法
    请求的起始行以方法作为开始,方法用来告知服务器要做些什么。比如,在行
    “GET /specials/saw-blade.gif HTTP/1.0”中,方法就是GET。
    HTTP规范中定义了一组常用的请求方法。比如,GET方法负责从服务器获取-一个
    文档,POST方法会向服务器发送需要处理的数据,OPTIONS方法用于确定Web
    服务器的-般功能,或者Web服务器处理特定资源的能力。
    表3-1描述了7种这样的方法。注意,有些方法的请求报文中有主体,有些则是无
    主体的请求。

    image.png

    并不是所有服务器都实现了表3-1列出的所有7种方法。而且,由于HTTP设计得
    易于扩展,所以除了这些方法之外,其他服务器可能还会实现-一些自己的请求方法。
    这些附加的方法是对HTTP规范的扩展,因此被称为扩展方法。,

    4.状态码
    方法是用来告诉服务器做什么事情的,状态码则用来告诉客户端,发生了什么事情。
    状态码位于响应的起始行中。比如,在行HTTP/1.0 200 OK中,状态码就是200。
    客户端向一个HTTP服务器发送请求报文时,会发生很多事情。幸运的话,请求会
    成功完成。但你不会总是那么幸运的。服务器可能会告诉你无法找到所请求的资源,
    你没有访问资源的权限,或者资源被移到了其他地方。
    状态码是在每条响应报文的起始行中返回的。会返回一个数字状态和一个可读的状
    态。数字码便于程序进行差错处理,而原因短语则更便于人们理解。
    可以通过三位数字代码对不同状态码进行分类。200 到299之间的状态码表示成功。
    300到399之间的代码表示资源已经被移走了。400到499之间的代码表示客户端
    的请求出错了。500到599之间的代码表示服务器出错了。,


    image.png

    当前的HTTP版本只为每类状态定义了几个代码。随着协议的发展,HTTP规范中
    会正式地定义更多的状态码。如果收到了不认识的状态码,可能是有人将其作为当
    前协议的扩展定义的。可以根据其所处范围,将它作为那个类别中一个普通的成员
    来处理。
    比如,如果收到了状态码515 (在表3-2所列5XX代码的已定义范围之外),就应该
    认为这条响应指出了服务器的错误,这是5XX报文的通用类别。
    表3-3列出了部分最常见的状态码。本章稍后会详细解释当前在用的所有HTTP状
    态码。

    image.png

    5.原因短语
    原因短语是响应起始行中的最后一个组件。它为状态码提供了文本形式的解释。比
    如,在行HTTP/1.0 200 OK中,OK就是原因短语。
    原因短语和状态码是成对出现的。原因短语是状态码的可读版本,应用程序开发者
    将其传送给用户,用以说明在请求期间发生了什么情况。
    HTTP规范并没有提供任何硬性规定,要求原因短语以何种形式出现。本章稍后列
    出了状态码和--些建议使用的原因短语。
    6.版本号
    版本号会以HTTP/x.y的形式出现在请求和响应报文的起始行中。为HTTP应用程序
    提供了--种将自己所遵循的协议版本告知对方的方式。
    使用版本号的目的是为使用HTTP的应用程序提供一种线索, 以便互相了解对方的
    能力和报文格式。在与使用HTTP 1.1的应用程序进行通信的HTTP 1.2 应用程序应
    该知道,它不能使用任何新的1.2特性,因为使用老版本协议的应用程序很可能无
    法实现这些特性。
    版本号说明了应用程序支持的最高HtTP版本。但HTTP/1.0应用程序在解释包含
    HTTP/1.1的响应时,会认为这个响应是个1.1 响应,而实际上这只是响应应用程序
    所使用的协议等级,在这些情况下,版本号会在应用程序之间造成误解了。
    注意,版本号不会被当作分数来处理。版本中的每个数字(比如HTTP/1.0中的1
    和0)都会被当作-一个单独的数字来处理。因此,在比较HTTP版本时,每个数字
    都必须单独进行比较,以便确定哪个版本更高。比如,HTTP/2.22 就比HTTP/2.3的
    版本要高,因为22比3大。

    3.2.3
    首部
    前一小节的重点是请求和响应报文的第一行(方法、状态码、原因短语和版本号)。
    跟在起始行后面的就是零个、一个或多个HTTP首部字段(参 见图3-5)。
    HTTP首部字段向请求和响应报文中添加了- - 些附加信息。本质上来说,它们只是-一
    些名1值对的列表。比如,下面的首部行会向Content - Length首部字段赋值19:
    Content- length: 19

    1.首部分类
    HTTP规范定义了几种首部字段。应用程序也可以随意发明自己所用的首部。HTTP
    首部可以分为以下几类。
    ●通用首部
    既可以出现在请求报文中,也可以出现在响应报文中。
    ●请求首部
    提供更多有关请求的信息。
    ●响应首部
    提供更多有关响应的信息。
    ●实体首部
    描述主体的长度和内容,或者资源自身。
    ●扩展首部
    规范中没有定义的新首部。,
    每个HTTP首部都有- -种简单的语法:名字后面跟着冒号( : ),然后跟上可选的空
    格,再跟上字段值,最后是一个CRLF。表3-4列出了一些常见的首部实例。

    image.png

    2.首部延续行
    将长的首部行分为多行可以提高可读性,多出来的每行前面至少要有一个空格或制
    表符(tab)。
    例如:
    HTTP/1.0 200 OK
    Content-Type: image/gif
    Content -Length: 8572
    Server: Test Server
    Version 1.0
    在这个例子中,响应报文里包含了一一个Server首部,其值被划分成了多个延续行。
    该首部的完整值为Test server Version 1.0。
    本章稍后将简要介绍所有的HTTP首部。附录C提供了所有首部更为详细的参考。

    3.2.4
    实体的主体部分
    HTTP报文的第三部分是可选的实体主体部分。实体的主体是HTTP报文的负荷。
    就是HTTP要传输的内容。
    HTTP报文可以承载很多类型的数字数据:图片、视频、HTML文档、软件应用程
    序、信用卡事务、电子邮件等。

    3.2.5
    版本0.9的报文
    HTTP版本0.9是HTTP协议的早期版本。是当今HTTP所拥有的请求及响应报文
    的鼻祖,但其协议要简单得多(参见图3-6)。

    image.png

    HTTP/0.9报文也由请求和响应组成,但请求中只包含方法和请求URL,响应中只
    包含实体。它没有版本信息(它是第一个,而且是当时唯一-的版本), 没有状态码或
    原因短语,也没有首部。

    但这种简单协议无法提供更多的灵活性,也无法实现本书中描述的大部分HTTP特
    性和应用。这里对其进行简要的描述,是因为仍然有一-些客户端、服务器和其他应,
    用程序在使用这个协议,应用程序的编写者应该清楚它的局限性。

    3.3
    方法
    现在,我们对前面在表3-1中列出的-一些基本HTTP方法进行更为深入的讨论。注
    意,并不是每个服务器都实现了所有的方法。如果一台服务器要与HTTP 1.1 兼容,
    那么只要为其资源实现GET方法和HEAD方法就可以了。
    即使服务器实现了所有这些方法,这些方法的使用很可能也是受限的。例如,支持
    DELETE方法或PUT方法(本节稍后介绍)的服务器可能并不希望任何人都能够删
    除或存储资源。这些限制通常都是在服务器的配置中进行设置的,因此会随着站点
    和服务器的不同而有所不同。

    3.3.1 安全方法
    HTTP定义了一组被称为安全方法的方法。GET方法和HEAD方法都被认为是安全
    的,这就意味着使用GET或HEAD方法的HTTP请求都不会产生什么动作。
    不产生动作,在这里意味着HTTP请求不会在服务器上产生什么结果。例如,你在
    Joe的五金商店购物时,点击了“提交购买”按钮。点击按钮时会提交-一个带有信
    用卡信息的POST请求(稍后讨论),那么在服务器上,就会为你执行一个动作。在
    这种情况下,为购买行为支付信用卡就是所执行的动作。
    安全方法并不一定是什么动作都不执行的(实际上,这是由Web开发者决定的)。
    使用安全方法的目的就是允许HTTP应用程序开发者通知用户,什么时候会使用某
    个可能引发某些动作的不安全方法。在Joe的五金商店的例子中,你的Web浏览器
    可能会弹出一-条警告消息,说明你正在用不安全的方法发起请求,这样可能会在服
    务器上引发一些事件(比如用你的信用卡支付费用)。

    3.3.2
    GET
    GET是最常用的方法。通常用于请求服务器发送某个资源。HTTP/1.1 要求服务器
    实现此方法。图3-7显示了一个例子,在这个例子中,客户端用GET方法发起了-一
    次HTTP请求。

    image.png

    3.3.3
    HEAD
    HEAD方法与GET方法的行为很类似,但服务器在响应中只返回首部。不会返回实
    体的主体部分。这就允许客户端在未获取实际资源的情况下,对资源的首部进行检
    查。使用HEAD,可以:
    ●在不获取资源的情况下了解资源的情况(比如,判断其类型) ;
    ●通过查看响应中的状态码,看看某个对象是否存在;
    ●通过查看首部,测试资源是否被修改了。
    服务器开发者必须确保返回的首部与GET请求所返回的首部完全相同。遵循
    HTTP/1.1规范,就必须实现HEAD方法。图3-8显示了实际的HEAD方法。

    image.png

    3.3.4
    PUT
    与GET从服务器读取文档相反,PUT方法会向服务器写入文档。有些发布系统允
    许用户创建Web页面,并用PUT直接将其安装到Web服务器上去(参见图3-9)。

    image.png

    PUT方法的语义就是让服务器用请求的主体部分来创建一个由所请求的URL命名
    的新文档,或者,如果那个URL已经存在的话,就用这个主体来替代它。
    因为PUT允许用户对内容进行修改,所以很多Web服务器都要求在执行PUT之
    前,用密码登录。在第12章中可以读到更多有关密码认证的内容。

    3.3.5
    POST
    POST方法起初是用来向服务器输入数据的。实际上,通常会用它来支持HTML
    的表单。表单中填好的数据通常会被送给服务器,然后由服务器将其发送到它要去
    的地方(比如,送到一个服务器网关程序中,然后由这个程序对其进行处理)。图
    3-10显示了一个用POST方法发起HTTP请求一向 服务器发送表单数据一-的客
    户端。
    3.3.6 TRACE
    客户端发起一个请求时,这个请求可能要穿过防火墙、代理、网关或其他一-些应用
    程序。每个中间节点都可能会修改原始的HTTP请求。TRACE方法允许客户端在,
    最终将请求发送给服务器时,看看它变成了什么样子。
    TRACE请求会在目的服务器端发起一个“环回”诊断。行程最后- -站的服务器会
    弹回一条TRACE响应,并在响应主体中携带它收到的原始请求报文。这样客户端
    就可以查看在所有中间HTTP应用程序组成的请求/响应链上,原始报文是否,以
    及如何被毁坏或修改过(参见图3-11)。

    image.png image.png

    TRACE方法主要用于诊断:也就是说,用于验证请求是否如愿穿过了请求/响应
    链。它也是一种很好的工具,可以用来查看代理和其他应用程序对用户请求所产生
    效果。
    尽管TRACE可以很方便地用于诊断,但它确实也有缺点,它假定中间应用程序对
    各种不同类型请求(不同的方法一GET、 HEAD、POST等)的处理是相同的。
    很多HTTP应用程序会根据方法的不同做出不同的事情一-比如,代理可能会将
    POST请求直接发送给服务器,而将GET请求发送给另一个HTTP应用程序(比如
    Web缓存)。TRACE并不提供区分这些方法的机制。通常,中间应用程序会自行决:
    定对TRACE请求的处理方式。
    TRACE请求中不能带有实体的主体部分。TRACE响应的实体主体部分包含了响应
    服务器收到的请求的精确副本。

    3.3.7
    OPTIONS
    OPTIONS方法请求Web服务器告知其支持的各种功能。可以询问服务器通常支持
    哪些方法,或者对某些特殊资源支持哪些方法。(有些服务器可能只支持对一些特殊
    类型的对象使用特定的操作)。
    这为客户端应用程序提供了一种手段,使其不用实际访问那些资源就能判定访问各
    种资源的最优方式。图3-12显示了一个使用OPTIONS方法的请求。

    image.png

    3.3.8
    DELETE
    顾名思义,DELETE方法所做的事情就是请服务器删除请求URL所指定的资源。
    但是,客户端应用程序无法保证删除操作一定会被执行。因为HTTP规范允许服务
    器在不通知客户端的情况下撤销请求。图3-13显示了一个DELETE方法实例。

    image.png

    3.3.9.
    扩展方法
    HTTP被设计成字段可扩展的,这样新的特性就不会使老的软件失效了。扩展方法.
    指的就是没有在HTTP/1.1规范中定义的方法。服务器会为它所管理的资源实现一
    些HTTP服务,这些方法为开发者提供了一种扩展这些HTTP服务能力的手段。表
    3-5列出了一些常见的扩展方法实例。这些方法就是WebDAV HTTP扩展(参见第
    19章)包含的所有方法,这些方法有助于通过HTTP将Web内容发布到Web服务
    器上去。

    image.png

    并不是所有的扩展方法都是在正式规范中定义的,认识到这一点很重要。 如果你定
    义了一个扩展方法,很可能大部分HTTP应用程序都无法理解。同样,你的HTTP
    应用程序也可能会遇到一些其他应用程序在用的,而它并不理解的扩"展方法。
    在这些情况下,最好对扩展方法宽容一些。如果能够在不破坏端到端行为的情况下
    将带有未知方法的报文传递给下游服务器的话,代理会尝试着传递这些报文的。否
    则,它们会以501 Not Implemented (无法实现)状态码进行响应。最好按惯例“ 对
    所发送的内容要求严. 点,对所接收的内容宽容一些”来处理扩展方法(以及一般
    的HTTP扩展)。

    相关文章

      网友评论

          本文标题:第三章:http报文

          本文链接:https://www.haomeiwen.com/subject/htdzgltx.html