php http请求报文格式,http1.1请求和响应报文格式

53b085e41a2dd4551c2118cc88130083.png

既然http2和http3都已经发布了,那么为什么还要学习http1.1呢?因为,首先还有很大一部分的网站依旧在使用http1.1。其次http2和http3都支持http1.1的所有核心功能,它们只是在原本的http1.1语义层之下采用了更高效的传输机制,因此理解http1.1对于理解http2和http3是有很大帮助的。

1. 请求报文

请求报文由4个部分组成,它们分别是请求行、请求头部、空行和报文主体;请求行、请求头部和空行是必需的而报文主体是可选的。

39a7df8249a45d9ba780c881a5358ada.png

图1 http1.1的请求报文格式

一个实际的http1.1请求报文如图2所示,该报文中第1行是请求行、第2至15行是请求头部、第16行是空行,剩余的是报文主体。

b036840d597a4b2d04bac72c37d10751.png

图2 一个实际的http1.1请求报文

1.1 请求行

请求行又包含3个部分:请求方法、URL和协议版本;它们之间用空格分开,请求行最后以一个回车符和一个换行符结尾。回车符是"\r",换行符是"\n";后面不再重复说明。

请求方法表明想对目标资源进行何种操作,http1.1定义了下表中列出的8种请求方法,其中最常用的是GET和POST。

f34671bf45114d73fe2fca835fa77f7a.png

URL字段用来指明目标资源的位置,它只包含一个完整URL中的文件路径和查询字符串这两部分,比如"/index.php?id=24",而不包含协议、主机名和端口号。如果同一服务器上部署了多个网站,那么为了准确判断出请求的是哪个资源需要将URL字段和Host请求头的值(指定要访问的网站名)相结合使用。

协议版本字段说明该请求报文属于哪一版的http协议,比如HTTP/1.1或HTTP/1.0。

1.2 请求头部

请求头部用来告知服务器该请求和客户端本身的一些额外信息,每个请求头都是一个键值对,键和值之间用英文冒号隔开。每个请求头单独形成一行,它们的末尾都是一个回车符和换行符。

在所有的请求头中,只有Host是必需的,其它请求头都是可选的。这里,我们将一些常见的请求头列于下表中:

d9fb1e42c868d2b7b8682a3824af3faa.png

1.3 空行

在请求头部的后面是一个空行,它只包含一个回车符和一个换行符,不包含其它任何内容,连空格也不能包含。这个空行用于标记请求头部已结束;它是必须要有的,即便使用GET这样不包含报文主体的请求方法时也要有这个空行。

1.4 报文主体

请求报文中的报文主体就是要提交给服务器的数据,比如当我们使用POST方法提交表单时,表单中的内容就包含在请求报文的报文主体中。在某些情况下请求报文中是没有报文主体的,比如使用GET方法,此时若要向服务器传递参数,那么参数就只能包含在URL的查询字符串(query string)中。

报文主体中的数据格式由Content-Type请求头指定,主要有两种格式,我们这里简单提一下。当Content-Type的值为application/x-www-form-urlencoded时,那么提交的数据就是以&分隔的多个键值对,每个键值对的键和值用等号连接,且数据还要经过URL编码。假设有一个让用户输入姓名、年龄和国籍的表单,那么提交的数据格式是这样的:name=Mike&age=22&country=America。

当需要上传大量的二进制数据(比如文件)的时候,应该使用multipart/form-data格式。此时Content-Type的值为"multipart/form-data; boundary=3vkqffBXJh"。其中3vkqffBXJh是自定义的分隔符,它用于分隔提交数据中的不同部分。你或浏览器可以随意指定它,不过它应该要能和其它内容相区别。

此时,提交数据的格式就像下面这样。数据中的每一部分都以--3vkqffBXJh的一行开始,它的形式是在分隔符前面添加两个连字符。紧接着的是这部分数据的消息头,消息头用于说明该部分数据的相关信息,类似于请求头。每个消息头占据单独的一行,其中Content-Disposition消息头是必需的而其它消息头是可选的。在所有消息头之后是一个空行,空行后才是该部分数据的实际内容,空行用于分隔消息头和实际数据。

276827d694a2452e96ff2f6d23301f1a.png

Content-Disposition的值中第一部分是固定不变的form-data,表明该部分数据是表单内容。第二部分是name="fieldName"这样的形式,指明该部分数据属于表单中的哪一个字段。如果这部分数据是文件的话,那么可能还有形如filename="fileName"的第三部分,它指定该文件的初始名称。对于文件数据,可能还有一个Content-Type消息头用于指定该文件的MIME类型。

此时整个报文主体以--3vkqffBXJh--的一行结束。注意,这一行的特殊之处在于分隔符的前后均有两个连字符。multipart/form-data格式的数据中每一行都以一个回车符和换行符结尾。

2. 响应报文

响应报文也由4个部分组成,它们分别是状态行、响应头部、空行和报文主体;状态行、响应头部和空行是必需的而报文主体是可选的。

0980e900dff9260548e2de4d0ae79f7b.png

图3 http1.1响应报文的格式

一个实际的http1.1响应报文如图4所示,第1行是状态行、第2到8行是响应头部、第9行是空行,后面的是报文主体(即响应的数据),该例子中的响应数据是一个html文档。

b5d145639810c16f21415d28cb4316ba.png

图4 一个实际的http1.1响应报文

2.1 状态行

状态行包含3个部分:协议版本、状态码和状态短语;它们之间用空格隔开,状态行的最后是一个回车符和换行符。协议版本和请求报文中的一样,表示该响应报文所属的http版本。

状态码是服务器返回的表示响应状态的代码,状态短语是对该响应状态的一个简单描述。常见的状态码和它们对应的状态短语如下表所示:

ff8bb2e8b6b3cc7c4696b30fe08b1fd3.png

注意:状态短语中的空格和分隔协议版本、状态码和状态短语的空格的含义是不一致的。前者是为了分隔状态短语中的单词,而后者是为了分隔状态行中的不同部分。

2.2 响应头部

响应头部和请求头部差不多,它用于传递一些附加的信息;每个响应头都是一个键值对,键和值之间用英文冒号隔开。每个响应头的后面都是一个回车符和一个换行符,即每个响应头单独形成一行。

某些头部字段既可以用于请求报文又可以用于响应报文,而有些则只能用于请求报文或者只能用于响应报文。一些常见的响应头如下表所示:

d50b2502d126ff7fd7406975010d7536.png

2.3 空行

在响应头部的后面是一个空行,它只包含一个回车符和一个换行符,不包含其它任何内容,即便是空格也不能有。它用于指定响应头部已结束,该空行是必不可少的,即便响应报文中没有报文主体也要有这个空行。

2.4 报文主体

响应报文中的报文主体就是服务端返回的数据,它的类型由响应头"Content-Type"说明。在某些响应报文中是没有报文主体(即响应数据)的,比如状态码为304(Not Modified)的响应报文或者某些请求错误时的响应报文。

(完)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值