Android 网络基础 -- HTTP 请求过程及理解

本文来自 图解 HTTP ,相关资料与图片均来自于该书

HTTP 通信过程中,从客户端到服务端的响应是怎么样的呢?这一章,我们一起来了解一下。

一、HTTP 报文

用于 HTTP 协议交互的信息被称为 HTTP 报文。 客户端的报文叫做请求报文,服务端的则叫响应报文。

HTTP 报文大致可分为报文首部报文主体两块。由换行符来区分,通常,并不一定有报文主体,如下图所示:
Android 网络基础 -- HTTP 请求过程及理解_第1张图片
请求报文 和 响应报文 的结构,大致可以分为
请求(响应)行 - 状态行 - 报文主体:
Android 网络基础 -- HTTP 请求过程及理解_第2张图片

  • 请求行 :包含用于请求的方法,请求 URI 和 HTTP 版本
  • 状态行 :包含表明影响结果的状态码,原因短语和 HTTP 版本
  • 首部字段 :表示请求和响应的各种条件和属性的各类首部,一般有4种,分别是:通过首部,请求首部,响应首部和实体首部。

一个实例如下:
Android 网络基础 -- HTTP 请求过程及理解_第3张图片

1.1 报文主体和实体主体的差异

  • 报文
    是HTTP通信中的基本单位,由 8 个字节流组成。
  • 实体
    作为请求或响应的有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。

怎么理解呢?先理解,主体是报文的一部分,如下面一段响应报文:

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 5
Zhihu

其中除了报文首部字段,实体其实就是 “Zhihu”,报文主体其实等于实体主体,但它并没有实体首部,只有实体主体,但如果是一个表单,则实体首部和实体主体就有了,如下:

POST /upload HTTP/1.1
Host: example.com
Content-Length: xxx
Content-Type: multipart/form-data; boundary=AaBbCcDd

--AaBbCcDd
Content-Disposition: form-data; name="username"

RuphiLau
--AaBbCcDd
Content-Disposition: form-data; name="file"; filename="picture.jpg"
Content-Type: image/jpeg

...(picture.jpg的数据)...
--AaBbCcDd--

1.2 压缩传输的内容编码

为了便于传输,通常会对原始内容进行原样压缩,再由接收端接收和解码,常用的内容编码有以下几种:

  • gzip (GNU zip)
  • compress (UNIX 系统的标准压缩)
  • deflaate (zip)
  • identity (不进行压缩)

1.3 分块传输编码

通常,如果实体内容过大,在未传输完成之前,浏览器无法实现请求页面;所以在传输大容量数据时,会把数据分割成多块,让浏览器逐步显示页面。
这种把主体分块的功能被称为 - 分块传输编码
分块传输编码,会把实体主体分成很多块,每一块都会特殊的十六进制来标记大小,而最后一块,则是使用 "0(CT_LF)"来标记。

这样,客户端在接收的时候,先检测到头部的大小信息,当接收的大小与头部信息吻合时,就说明这个块接收完成了,当所有的块接收完成时,整个实体信息也就接收完成了。
这种思想,也常常用在 socket 传输的粘包粘包的处理上。

1.4 发送多种数据对象

当 HTTP 想发送多种类型的数据时,该怎么处理呢?

这里可以借鉴邮件发送,邮件发送可以发送文字、视频、图片等附件;这里因为采用了 MIME(多部分对象) 机制。它允许邮件处理文本、图片、视频等多个不同类型的数据。

响应的,HTTP 也采用了这一机制,发送的报文主体内可含多种类型实体。通常是在图片或 文本上传时使用。
对象集合包含的如下:

  • mulripart/form-data : 在 Web 表单文件上传时使用
  • mulpart/byteranges : 状态码 206 (部分内容),响应报文包含多个范围的内容时使用,比如 Range 属性。

当要使用多部分对象时,需要在首部字段里加上 Content-type。关于这些字段,咱们后面再讲。

1.5 获取部门内容

当我们要获取一个大文件时,为了防止网络中断的情况,从而从头开始下的问题。就需要一个可恢复的机制,即从之前的下载中断处恢复下载。

要实现该功能需要指定下载的实体 范围,这个请求范围,可以使用 Range 的头部信息来指定,格式如下:

  • 5001 ~ 10000 个字节 : Range: bytes=5001-10000
  • 从 5001 之后的全部:Range:bytes=5001 -
  • 从开始到3000字节,和 5000 到 7000 字节的多种范围

注意,当针对请求范围时,返回的状态码为 206 的响应报文,如果服务器不支持,则返回 200 和全部实体。
Android 网络基础 -- HTTP 请求过程及理解_第4张图片

1.6 内容协商

同一份 Web 请求,可能返回的多份相同内容的页面,比如英文版和中文版的 Web 页面。尽管内容相同,但是语言却是不同的。

当客户端和服务端就响应的资源内容进行交涉,然后提供给客户端最合适的资源,这种机制,叫做内容协商。

内容协商会以响应资源的语言、字符集、编码方式等作为判断依据。包含在请求报文中的某些首部字段,如:

  • Accept
  • Accept-Charset
  • Accept-Encoding
  • Accept-Language
  • Content-Language

关于首部字段,后面再讲。

二、HTTP 状态码

状态码的职责是当客户端向服务端发起请求时,描述返回的请求结果。根据状态码,就可以知道服务端是正常处理了请求,还是出现了错误。
状态码 如 200 OK ,以 3 位数字和原因短语组成。
类别如下:
Android 网络基础 -- HTTP 请求过程及理解_第5张图片
状态码的数量非常多,但我们只需要记住14个常用的就可以了:

2xx的响应结果表示请求被正常处理了

  • 200 :OK 服务端正常处理了请求
  • 204 :NO Content,正常处理,但没有资源可返回;即报文中,没有实体部分。一般当客户端只向服务端发送消息而不需要更新什么的情况下使用。
  • 206 :范围请求 ,一般用于 Content-Range 指定范围的请求。

3xx 响应结果表示浏览器需要执行某些特殊的处理,才能正确处理请求
关于3xx的详细解释,可以参考这篇文章 https://www.cnblogs.com/wuguanglin/p/redirect.html

  • 301 : 永久性重定向,表示客户端请求的资源已经被分配了新的URI ,即请求的 URI 被定为到新的地址,此时服务器会返回新的地址,客户端重新访问这个新地址即可。这是应该按 Location 首部字段提示的 URI 重新保存。
    Android 网络基础 -- HTTP 请求过程及理解_第6张图片
  • 302 :临时重定向。该状态码表示该资源已经被分配了新的 URI ,希望本次能使用新的 URI 访问。
  • 303 : 表示请求的资源存在另一个 URI,应使用 GET 方法定向获取请求的资源。

当 301,302,303 状态码返回时,几乎所有的浏览器都会把 POST 改成 GET ,并删除请求报文内的主体,之后请求会自动再次发送。
301,302,是禁止把 POST 改成 GET 的,但实际大家都会这么 做。

  • 304 : 表示当客户端发送附带条件的请求时,服务器允许响应,但是请求条件未满足时,直接返回304.
  • 307 : 临时重定向。与 302 有关系,但是 302 不允许把 POST 改成 GET ,实际大家都会这么做;但 307 则不会把 POST 改成 GET ,而是遵照浏览器标准,根据可能出现不同的结果。

4xx 的响应结果表示客户端是发生错误的原因所在。

  • 400:Bad Request,客户端的请求报文中存在错误。
  • 401:Unauthorized,表示请求需要通过 HTTP 认证,若之前已进行 1 次请求,则表示用户认证失败。
  • 403:Forbidden,访问的资源被服务器拒绝了。
  • 404:Not found,服务器没有该资源。

5xx 表示服务器本身发啊生错误无。

  • 500:Internal Server Error,表示服务器执行请求时,发生了错误,也可能是 Web 的问题。
  • 503:Service Unavailable,服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

三、与HTTP协作的服务器

3.1 单台主体实现多个域名

HTTP 允许一台 HTTP 服务器搭建多个 Web 站点,比如,一个服务器,有多个域名,www.ssgodie.win 和 www.ggdie.win 都可以指向同一个服务器,因为它们指向的ip都是指向这台服务器的。

3.2 代理

代理服务器英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息。形象的说:它是网络信息的中转站。

在一般情况下,我们使用网络浏览器直接去连接其他Internet站点取得网络信息时,须送Request信号来得到回答,然后对方再把信息以bit方式传送回来。
代理服务器是介于浏览器和Web服务器之间的一台服务器,有了它之后,浏览器不是直接到Web服务器去取回网页而是向代理服务器发出请求,Request信号会先送到代理服务器,由代理服务器来取回浏览器所需要的信息并传送给你的浏览器。
而且,大部分代理服务器都具有缓冲的功能,就好象一个大的Cache,它有很大的存储空间,它不断将新取得数据储存到它本机的存储器上,如果浏览器所请求的数据在它本机的存储器上已经存在而且是最新的,那么它就不重新从Web服务器取数据,而直接将存储器上的数据传送给用户的浏览器,这样就能显著提高浏览速度和效率。更重要的是:Proxy Server(代理服务器)是Internet链路级网关所提供的一种重要的安全功能。

3.3 网关

从一个房间去另一个房间,必须经过一扇门,同样,从一个网络访问另一个网络,也需要 “关口”,
这就是网关。Android 网络基础 -- HTTP 请求过程及理解_第7张图片
那么网关到底是什么呢?网关实质上是一个网络通向其他网络的IP地址。
比如有网络A和网络B,
网络A的IP地址范围为“192.168.1.1~192. 168.1.254”,子网掩码为255.255.255.0;
网络B的IP地址范围为“192.168.2.1~192.168.2.254”,子网掩码为255.255.255.0。

在没有路由器的情况下,两个网络之间是不能进行TCP/IP通信的,即使是两个网络连接在同一台交换机(或集线器)上,TCP/IP协议也会根据子网掩码(255.255.255.0)判定两个网络中的主机处在不同的网络里。

而要实现这两个网络之间的通信,则必须通过网关。如果网络A中的主机发现数据包的目的主机不在本地网络中,就把数据包转发给它自己的网关,再由网关转发给网络B的网关,网络B的网关再转发给网络B的某个主机。网络A向网络B转发数据包的过程。

所以说,只有设置好网关的IP地址,TCP/IP协议才能实现不同网络之间的相互通信。

那么这个IP地址是哪台机器的IP地址呢?

网关的IP地址是具有路由功能的设备的IP地址,具有路由功能的设备有路由器、启用了路由协议的服务器(实质上相当于一台路由器)、代理服务器(也相当于一台路由器)。

3.3 隧道

网络隧道是一个特殊的网络协议,它利用一种网络协议来传输另一种网络协议,它主要利用网络隧道协议来实现这种功能。届时使用 SSL 等加密手段啊进行通信。
隧道本身不会去解析HTTP请求,也就是说,请求保持原样中转给之后的服务器,隧道会在通信双方断开连接时结束。
Android 网络基础 -- HTTP 请求过程及理解_第8张图片

你可能感兴趣的:(Android-网络,HTTP请求,代理,网关,隧道)