本文来自 图解 HTTP ,相关资料与图片均来自于该书
HTTP 通信过程中,从客户端到服务端的响应是怎么样的呢?这一章,我们一起来了解一下。
用于 HTTP 协议交互的信息被称为 HTTP 报文。 客户端的报文叫做请求报文,服务端的则叫响应报文。
HTTP 报文大致可分为报文首部和报文主体两块。由换行符来区分,通常,并不一定有报文主体,如下图所示:
请求报文 和 响应报文 的结构,大致可以分为
请求(响应)行 - 状态行 - 报文主体:
怎么理解呢?先理解,主体是报文的一部分,如下面一段响应报文:
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--
为了便于传输,通常会对原始内容进行原样压缩,再由接收端接收和解码,常用的内容编码有以下几种:
通常,如果实体内容过大,在未传输完成之前,浏览器无法实现请求页面;所以在传输大容量数据时,会把数据分割成多块,让浏览器逐步显示页面。
这种把主体分块的功能被称为 - 分块传输编码
分块传输编码,会把实体主体分成很多块,每一块都会特殊的十六进制来标记大小,而最后一块,则是使用 "0(CT_LF)"来标记。
这样,客户端在接收的时候,先检测到头部的大小信息,当接收的大小与头部信息吻合时,就说明这个块接收完成了,当所有的块接收完成时,整个实体信息也就接收完成了。
这种思想,也常常用在 socket 传输的粘包粘包的处理上。
当 HTTP 想发送多种类型的数据时,该怎么处理呢?
这里可以借鉴邮件发送,邮件发送可以发送文字、视频、图片等附件;这里因为采用了 MIME(多部分对象) 机制。它允许邮件处理文本、图片、视频等多个不同类型的数据。
响应的,HTTP 也采用了这一机制,发送的报文主体内可含多种类型实体。通常是在图片或 文本上传时使用。
对象集合包含的如下:
当要使用多部分对象时,需要在首部字段里加上 Content-type。关于这些字段,咱们后面再讲。
当我们要获取一个大文件时,为了防止网络中断的情况,从而从头开始下的问题。就需要一个可恢复的机制,即从之前的下载中断处恢复下载。
要实现该功能需要指定下载的实体 范围,这个请求范围,可以使用 Range 的头部信息来指定,格式如下:
注意,当针对请求范围时,返回的状态码为 206 的响应报文,如果服务器不支持,则返回 200 和全部实体。
同一份 Web 请求,可能返回的多份相同内容的页面,比如英文版和中文版的 Web 页面。尽管内容相同,但是语言却是不同的。
当客户端和服务端就响应的资源内容进行交涉,然后提供给客户端最合适的资源,这种机制,叫做内容协商。
内容协商会以响应资源的语言、字符集、编码方式等作为判断依据。包含在请求报文中的某些首部字段,如:
关于首部字段,后面再讲。
状态码的职责是当客户端向服务端发起请求时,描述返回的请求结果。根据状态码,就可以知道服务端是正常处理了请求,还是出现了错误。
状态码 如 200 OK ,以 3 位数字和原因短语组成。
类别如下:
状态码的数量非常多,但我们只需要记住14个常用的就可以了:
2xx的响应结果表示请求被正常处理了
3xx 响应结果表示浏览器需要执行某些特殊的处理,才能正确处理请求
关于3xx的详细解释,可以参考这篇文章 https://www.cnblogs.com/wuguanglin/p/redirect.html
当 301,302,303 状态码返回时,几乎所有的浏览器都会把 POST 改成 GET ,并删除请求报文内的主体,之后请求会自动再次发送。
301,302,是禁止把 POST 改成 GET 的,但实际大家都会这么 做。
4xx 的响应结果表示客户端是发生错误的原因所在。
5xx 表示服务器本身发啊生错误无。
HTTP 允许一台 HTTP 服务器搭建多个 Web 站点,比如,一个服务器,有多个域名,www.ssgodie.win 和 www.ggdie.win 都可以指向同一个服务器,因为它们指向的ip都是指向这台服务器的。
代理服务器英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息。形象的说:它是网络信息的中转站。
在一般情况下,我们使用网络浏览器直接去连接其他Internet站点取得网络信息时,须送Request信号来得到回答,然后对方再把信息以bit方式传送回来。
代理服务器是介于浏览器和Web服务器之间的一台服务器,有了它之后,浏览器不是直接到Web服务器去取回网页而是向代理服务器发出请求,Request信号会先送到代理服务器,由代理服务器来取回浏览器所需要的信息并传送给你的浏览器。
而且,大部分代理服务器都具有缓冲的功能,就好象一个大的Cache,它有很大的存储空间,它不断将新取得数据储存到它本机的存储器上,如果浏览器所请求的数据在它本机的存储器上已经存在而且是最新的,那么它就不重新从Web服务器取数据,而直接将存储器上的数据传送给用户的浏览器,这样就能显著提高浏览速度和效率。更重要的是:Proxy Server(代理服务器)是Internet链路级网关所提供的一种重要的安全功能。
从一个房间去另一个房间,必须经过一扇门,同样,从一个网络访问另一个网络,也需要 “关口”,
这就是网关。
那么网关到底是什么呢?网关实质上是一个网络通向其他网络的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地址,具有路由功能的设备有路由器、启用了路由协议的服务器(实质上相当于一台路由器)、代理服务器(也相当于一台路由器)。
网络隧道是一个特殊的网络协议,它利用一种网络协议来传输另一种网络协议,它主要利用网络隧道协议来实现这种功能。届时使用 SSL 等加密手段啊进行通信。
隧道本身不会去解析HTTP请求,也就是说,请求保持原样中转给之后的服务器,隧道会在通信双方断开连接时结束。