HTTP工作方式与报文解析

       HTTP是我们在开发工作中经常接触而又容易被忽视的知识点。它经常是“一次配置,终身使用”。即在第一次被搭建起来,后面基本不会再动它。前端、后端,以及前后端交互的代码都已经定型。而我们只需要按照之前的规则来对他进行扩展。这就导致了我们经常使用,但对它又并不是很了解。

       本文将通过介绍HTTP协议的定义、工作方式,以及请求报文和响应报文的解析,帮助大家更好的理解HTTP协议。

  • 一、HTTP基础

1.1 HTTP是什么?

对我们来说最直观的理解,HTTP可能就是我们在浏览器输入一个地址,打开网页。或者,在Android中发送网络请求,返回响应的内容。

HTTP,实际上是HyperText Transfer Protocol的缩写,翻译过来就是“超文本传输协议”。这里的“超文本”,指的是含有指向其他文本的链接文本,它和“超链接”是一个意思。协议,既是指通讯双方共同定义的一套通讯规范。

1.2 HTTP和HTML

HTTP最早就是用来传递HTML文本的。HTTP和HTML几乎是同时诞生。早期学术界的人,需要在网页浏览文章,以及对知识进行产出和交流。而HTML格式,可以在浏览器上展示带有一定排版的文章,并且可以用纯文本的方式来传输页面。

1.2 HTTP的工作方式

 HTTP的大概工作过程是:用户通过浏览器把请求发出去,服务器拿到请求后进行处理,比如查找某个页面等。服务器处理完毕,将结果返回给浏览器。浏览器拿到响应内容将其渲染出来,成为可见的文字、图片等。

我们常说的内核就是浏览器的渲染引擎,负责对服务器响应的内容进行渲染。手机端工作方式也与这个过程类似。请求和渲染从浏览器变成手机APP。

我们在浏览器中输入的URL信息,实际会转为HTTP报文在网络上传输。例如,

http://www.mytest.com/users?gender=male

    转为HTTP报文:

GET /users?gender=male HTTP/1.1

Host: www.mytest.com

HTTP报文分为请求报文和响应报文。

1.3 请求报文

请求报文主要包括:请求行、Header和Body三个部分。

请求行,包括method、path和version三个部分。method,表示哪一类请求,我们常用的有Get、Post等,后面章节在做详细介绍;path,表示所访问资源在服务器的路径,用于定位资源位置;version,表示HTTP协议版本号,到目前有四个版本0.9、1.0、1.1和2.0。其中0.9和1.0版本已经废弃,目前大量使用的是1.1版本。当前2.0版本还没有被广泛使用,大量普及还需要时间。

Header,是首部,以键值对的形式展现,可以一行也可以多行。它是HTTP消息的metadata(metadata,元数据,对数据进行修饰的数据)。后面章节将将对Header中常用的键及作用进行详细的介绍。

Body,数据部分,客户端发给服务器的信息主体。

1.4 响应报文

 响应报文包括状态行、Heder和Body三部分。与请求报文不同的是状态行部分。它由版本号、状态码和状态信息三个部分。状态码和状态信息,是服务器返回的快速定位问题的信息。后面章节将详细讨论。

  • 二、请求和响应

2.1 请求方法

请求方法是客户端根据不同业务类型进行不同的请求方式,有Get、Post、Put、Delete、Head五种。

Get

表示获取资源,没有Body,同时它是早期http 0.9版本唯一提供的方法。这里我们讨论标准用法。有些地方,尤其一些小公司,服务端客户端开发都在内部,不需要和外部进行沟通,你可能会看到带有Body的Get请求。这其实是一种不规范的写法。

对于HTTP,建议大家能够学习和了解协议的规范,并且按照规范使用它。不规范的写法,除了影响公司外部的合作,同时还会发生各种各样的问题。比如后端提供带有Body的Get接口,客户端使用retrofit进行访问,就会报出“IllegalArgumentExcetion Non-body HTTP method cannot contain Body”异常。

Post

用来增加或者修改资源,必须带有Body,Body内容表示需要向服务器提供的增加或者修改的内容。

Put

进行修改资源,带有Body,表示需要服务器修改的内容。这个也可以使用Post来实现,主要取决与后端接口如何设计。

Delete

删除资源,没有Body。只需要定位到待删除的资源即可。如,

DELETE /user/1 HTTP/1.1

Host: api.github.com

Head

用与获取资源,没有Body,类似与Get请求。不同的是,服务器返回的响应报文没有Body。它的作用通常是在请求发起之前,获取资源相关的信息。比如资源的大小、是否支持断电续传等等,这些信息是包含在响应报文的Header被返回的。拿到这些信息后,为后续真正的资源请求做准备。

上述五种请求之中,除了Post请求,其他Get、Put、Delete、Head请求都具有幂等性(幂等性,执行一次和多次,结果是一样的)。

2.2 响应状态码

响应状态码,是服务器对响应结果做类型化的描述,方便程序员快速进行定位和调试。主要有五种类型,分别是1、2、3、4、5开头的数字。

1xx:临时性消息,基本只有100和101两种。

100,表示消息继续发送。当客户端内容一次发不完,需要分多次发送。服务器每收到一次,返回100,表示这一包收到了,请继续发。

客户端:expert:100-continue,发送一包数据,后面还有数据要发送。

服务端:HTTP/1.1 100,这一包收到了,请你继续发。

101,表示协议切换。当客户端询问服务器端是否支持HTTP2.0协议,服务器返回101表示可以支持。

客户端:ugrade:h2c,询问服务器是否支持HTTP2.0协议。

服务端:HTTP/1.1 101,支持HTTP2.0,可以用该协议沟通;

        HTTP/1.1 200,不支持HTTP2.0,还是得用1.1版本。

2xx:表示成功,服务器收到消息并处理完成。最常见的是200。其他表示多种类型操作成功,201表示资源创建成功。

3xx:表示资源重定向。主要用301和302两个。301表示资源永久迁移;302表示资源临时性迁移。

4xx:表示客户端错误。因为请求本身的错误,导致服务器无法进行处理。如404表示请求的资源不存在,401表示访问未授权,需要先进行登录认证。

5xx:表示服务器错误。如服务器资源、空间不足等导致请求无法处理等。

  • 三、Header详解

前面提到Header提供HTTP消息的元数据(metadata)。既是对消息进行修饰的数据,也可以认为是消息的属性数据。

3.1 Host

表示目标主机地址和服务器地址。一个主机上可能会运行多个服务器,请求发起之前,DNS(域名服务器)通过Host查询目标主机的IP地址。请求到达主机之后,再根据Host字段查询具体的服务器。

这个字段有两个作用,给DNS查询主机IP,以及给主机查询主机上运行的服务器。

3.2 Content-Type

表示数据的类型,它有五种。

       1、text/html

       html文本,最基本和原始的类型,传递html文本。

       2、application/x-www-form-urlencodecd

       普通表单,传递纯文字的键值对形式。键值对之间用&进行连接。不能发送文件、图片等。形式如下:

   

       3、multipart/form-data

       多部分形式,用于传输包含二进制内容的多项内容。允许发送文件,使用boundary定义的字串对多个部分进行分界,这个字串是每次发送时随机生成的。boundary定义字串理论上存在和消息内容重复的问题。不过这个问题不用担心,因为一方面概率极低;另一方面即使发生了,则会发送失败,重发一次即可。

   

       4、application/json

       传递json字串。这种方式,让我们可以用json字串的方式发送请求或者响应消息。它比url形式具有更好的扩展性。

Json请求报文和响应报文:

   

       5、image/jpeg (application/zip …)

       单文件,用于传递单个文件,如文本、图片、视频等。

这种形式使用的很少。主要是因为很多人并不知道这种格式的存在。早期的互联网是以PC为主,很少有需要单文件上传的情形。而后来进入到移动互联网时代,单文件上传的需求开始大量出现,比如常见的换头像、单独传送一个文件等。在需求发生变化时,由于早期开发的惯性,很多开发者还是继续使用multipart/form-data的类型进行单文件传递。

后移动互联时代,单文件上传的业务情形,建议大家使用更加专业的单文件的类型。

这种类型的请求和响应保卫呢如下:

       

3.3 Content-Length

这个字段的作用指定Body长度。Body数据实际上是发送二进制数据,因此无论定义什么字符作为结束标志,都有可能出现和发送的内容重复。因此HTTP使用Content-Length指定发送Body的长度,让接收方可以知道需要多少个字符。

3.4 Transfer-Encoding:chunked

表示分块传输编码。如果,对于一个请求,服务器需要处理很长时间,或者需要返回的结果数据太大,需要多次进行返回。则可以分块将数据多次发送到客户端。客户端拿到部分数据后可以先进行处理,提升响应速度。

分块传输的响应报文形式如下,数字表示这一块传数据的大小,最后传输“0”表示内容传输结束。

3.5 Location

表示重定向的目标地址。当服务器发生临时性或永久迁移,则在响应报文中提供重定向的目标地址。浏览器解析该目标地址,会自动帮我们向目标地址重新发起请求。

3.6 User-Agent

表示用户代理,既是我们说的客户端。表示请求由谁发起,响应报文由谁接收和处理。例如服务器可以通过该字段了解,发起请求和接收响应的是手机APP或者某个浏览器。根据不同的终端返回不同的内容,方便客户端进行渲染,进行更好的适应。

3.7 Range/Accept-Ranges

表示支持分段加载。客户端可以接收指定范围的数据。

Accept-Range: bytes 响应报⽂中,表示服务器⽀持按字节来取范围数据

Range: bytes=<start>-<end> 请求报⽂中,表示要取哪段数据

Content-Range:<start>-<end>/total 响应报⽂中,表示发送的是哪段

它的作用可以用于支持断点续传和多线程下载。

断点续传很好理解,客户端记录断开连接前的字节数,连接恢复后,再请求该字节位置之后的信息。

多线程下载,就是客户端开多个线程,每个线程请求不同范围的数据,提高下载的吞吐量。服务器出于性能考虑,会限制每个接入端口的带宽,如限制50kb,当前网络带宽是5mb,则当前服务器理论最多可支持100个连接,5mb / 50kb = 100。如果不限速,一个连接占用1mb带宽,则它只能同时支持5个连接。有些下载软件,利用这个特点,开启多个端口,同时进行下载,绕过服务器带宽限制。这样就需要服务器能够支持分段加载。

3.8 其他字段

其他还有一些常用字段如下。大家看一下即可,很好理解,不再赘述。

Accept: 客户端能接受的数据类型。如 text/html

Accept-Charset: 客户端接受的字符集。如 utf-8

Accept-Encoding: 客户端接受的压缩编码类型。如 gzip

Content-Encoding:压缩类型。如 gzip

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值