http请求报文详解

         我们点击连接打开的每一个网页,都是网站的服务器发送给我们的,而点击连接这个动作,其实就是在向网站的服务器发送一个请求,告诉网站的服务器我们想要的东西是什么。网站服务器每天要面对很多的请求,如果每个请求都按照自己的意愿发送有个性的请求,显然,服务器是要崩溃的,因为,它忙不过来嘛,于是,聪明的人类坐在一起商量了一下,仔细的指定了请求的方式和服务器应答的方式,这就是大家耳熟能详的http协议。


         协议是个好东西,任何人开发出的任何产品只要符合http协议,就能够准确无误的提供服务。你想写一个浏览器,那么你不必关系网站的服务器是怎么工作的,你想写一个http服务器,那么你也不必关心浏览器是怎么工作的,你只要保证自己的程序遵守http协议就可以了。


        OK,现在我们开研究一下,http请求报文究竟长什么样,了解了这些,你就可以写一些简单的tcp socket和网站进行对话了。


        所有的http请求头报文都有着固定的格式:

        

<method> <request-URL> <version>
<header1>
<header2>
<header3>

<entity-body>


         

        method: 请求的方法,它告诉服务器,这次请求的方法是什么,常见的方法有GET,POST,我们在浏览器里输入地址,然后点击回车,这其实就是在发送一个GET方法的请求报文,我们平常登录网站,填写用户名和密码后点击登录,这个基本上就是在发送POST方法。


request-URL: 这个呢,就是我们要请求的资源的URL地址,服务器收到这个地址以后,就会访问获取相应的资源,它可能是一个网页,也可能是一个网站提供的下载资源,但是,一定要明确,这个request-URL绝不是我们在浏览器里看到的那个地址,现在我们随便找来一篇文章的地址: http://www.csdn.net/article/2015-08-22/2825515,这个是我们在浏览器里看到的,而实际发出去的报文中,request-URL 是/article/2015-08-22/2825515 ,此刻,部分读者可能会感到迷惑了,请求的地址不完整啊,诸位客官,稍安勿躁,在介绍headers时再做说明


        version : 这个就简单了,协议这个东西,自然是有版本的,一个版本用了一段时间后,发现有问题,时代在进步,技术在革新,老的版本跟不上时代了,自然就出新的版本,这东西就跟微信发布新版本是一样的,不同的是,http协议事关重大,不能那么频繁的更新版本,目前,大家用的都是 HTTP/1.1


        header: 术语叫做首部,可以有一个或者多个,这东西很简单,就是一个键值对,举个例子,还是这个网址http://www.csdn.net/article/2015-08-22/2825515,它发出去的请求报文中,其中就有一个header,内容是这样的 host:www.csdn.net  ,部首,也就是这些header,提供很多重要的信息,这直接关系到服务器如何响应。就拿这个host来说吧,如果没有它,很多网站是不能访问的。我们访问的网站,都有自己的IP地址,这个IP和我们自己电脑上的IP是不一样的,我们自己电脑里的IP是局域网里的IP,而服务器上的IP是公网里的IP,这么说不是很好理解,简单说,在你电脑上部署一个网站,那么我们是无法访问的,除非,我们用同一个路由器连接在一起,而服务器上部署一个网站,我们大家就都可以访问。虽然我们都能访问,但不只是一个网站在用这个IP地址,很多小网站其实是在共一个IP地址,每个网站都运行在虚拟主机上面。那么问题来了,那么多网站,收到那么多的请求,都指向了同一个IP地址,你访问A网站,我访问C网站,他们是如何区分我们发出去的请求呢?就是用这个host,ip地址虽然相同,但是host不相同啊,根据这个host,我们的请求就能到达我们所期望的那个网站,然后网站再根据request-RUL返回给我们想要的东西


       注意看,我一共写了三个header,部分聪明的客观此时一定有疑问了,这些header是随便定义的么?当然可以,但是,我们要明白,http协议为的是让客户端和服务器能够准确的互相理解对方,所以,规定了很多部首,这些部首有些是只能用于http请求报文的,有些是只能用于http相应报文的,还有一些是两边都能用的。一个key,一个value,组成了一个header,如果你自己定义了一个新的部首,key就定义为 love,然后value呢,定义为mother,你把这个部首放在请求头的报文里是没有问题的。但是,服务器看不懂啊,虽然它不会出错,但是服务器也理解不了这是个啥东西,因为,http协议里没有这个部首。那么你说,我自己来写这个服务器呢,我自己知道这个部首代表什么,那OK啊,没有问题的。


       最后说entity-body,这个东西呢,其实就是你想发送给服务器的数据,对于get请求,我们没有什么要发送给服务器的,即便有,也可以放在request-URL里。而对于post请求,比如上传一个文件,就需要用到entity-body了,我们需要把文件写入到entity-body里,具体的格式我不清楚,有明白的朋友劳烦您分享一下。


       注意看,在最后一个header和entity-body中间,隔了一空行,这个空行是万万不能缺少的,我们一再强调协议,协议就是大家都约定好的事情,协议说,最后一个header和entity-doby之间有一个空行,那么我们发出去的任何请求都必须严格执行这个协议,即便没有entity-doby,我们也要在最后一个header后面加上空行。这是规定,这是协议,服务器要依靠这些协议来解析请求报文。


       现在,我们一起捋一捋,就知道服务器如何解析请求报文了。


       第一行,术语叫做请求行,服务器获取第一行也就是请求行以后,就按照 method  request-URL  version 这个格式来解析,他们三个中间用空格隔开。比如 GET  /article/2015-08-22/2825515  HTTP/1.1  


       从第二行开始,就是术语里所谓的部首,部首有多个,刚才已经介绍了host,下一篇将专门介绍部首


       部首有多个,逐行的读取解析,当读到一空行的时候,服务器明白了,这时,所有的部首都已经解析完了,空行下面就是entity-body,也就是实体部分,这部分可能有,也可能没有,但是服务器非常清楚的知道,如果有,就一定在空行的后面,而且是紧挨着空行,于是,服务器再去空行后面解析实体部分。


       到此,我们已经知道http请求的基本格式了,其实,我们现在就可以写一个简单的tcp socket,连接一个网站的80端口,然后就按照我们刚才了解到的http请求报文的格式发送请求,网站收到请求后也会将响应内容返回给我们,这个程序将在下一篇介绍请求部首时给出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值