深入HTTP

129 阅读6分钟

前言

上一篇文章中,我们介绍了一下数据包的传输过程,并通过这个案例,连贯的讲解了一下 IP、UDP、TCP的内容,今天,我们就来深入了解一下 HTTP 的相关知识。

HTTP

http 也是一种协议,协议是什么呢?协议就是需要公共遵守的通信规则。就好比一个英国人和一个法国人在中国相遇了,他们需要沟通,那么他们就必须一起使用同一种语言比如说中文来进行交流,这样,他们想要传递的信息才会被对方正确的接受,这就是协议。而 http,是一种浏览器与服务器之间的通信协议,它是 web 应用的基础。

通常,沟通的发起端是浏览器,浏览器通过 http 协议向服务器发起资源请求,用来获取 HTML文件、CSS文件、JS文件、图片、视频等。

HTTP 的请求流程

如果你在浏览器的地址栏里输入了一个网址然后按下了回车键,那么接下来,浏览器会干哪些事呢?

  1. 构建请求。首先,浏览器会构建好 HTTP 请求行,并准备发起网络请求

  2. 查找缓存。但是,在真正发起网络请求之前,浏览器会现在缓存里查找一下是否有本次需要请求的文件,其中,浏览器缓存是一种在本地保存请求资源副本的技术,当浏览器发现请求资源已经存在在缓存中时,它会拦截请求,并直接返回该资源的副本然后结束请求,而不会再去从服务器端下载。(这里有个问题,真实情况下,浏览器对本地缓存的处理并不是这么简单的,不是说一查到有缓存就直接交给了渲染进程,这里面还有一个比较复杂的缓存协商过程,这个我们放在后面讲)

    这种缓存技术能有效缓解服务器的压力,提升网站性能(获取资源耗时变短),是 web 应用实现快速资源加载的重要组成部分。

    当然,如果缓存查找失败,则会进入网络请求过程。

  3. 准备 IP 地址和端口。在讲网络请求之前,我们先来看一下 HTTP 和 TCP 之间的关系。首先,HTTP 是基于 TCP/IP 的,其次,HTTP 属于应用层协议,既然讲到这里,那我们顺便再讲一下网络的七层模型。

    网络的七层模型分别叫做:应用层、表示层、会话层、传输层、网络层、数据链路层和物理层,为了简化模型,前三层其实可以并为一层,都叫应用层,这样处理之后,就是我们熟悉的五层模型。

    好,我们先把思路拉回来,上面我们也说了,http 它是属于应用层协议,它的构建是在应用层,但是它的使用,也就是它的发送时机则是在 TCP 连接建立好之后。

    到这里,我们来从头捋一下。前面我们讲过了,我们需要进行数据交互,需要发送数据包,就必须要知道两个信心,一个对方主机的 IP 地址,一个对方应用的端口号,这样我们才能把数据包正确的发送到目的主机的目标应用上去。那么问题来了,我们只是在浏览器里输入了一个网址,怎么来得到上面这些信息呢?

    IP 就是一串数字,比如说掘金的 IP 就是 122.225.209.220,比较难记忆,但是使用 juejin.cn 就好记多了。于是,基于这个问题,市面上又出现一种新的服务,这种服务负责把域名(juejin.cn)和 IP 地址做一一映射关联,这套域名映射的服务就叫做域名系统,简称 DNS(Domain Name System)。

    这样一来你会发现,发送 http 请求之前浏览器会先请求 DNS 拿到对应的 IP,当然,浏览器还提供了 DNS 缓存服务,如果某个域名已经被解析过了,那么浏览器会缓存下解析的结果以供下次查询的时候直接使用。拿到 IP 之后,接下来就是端口号了,通常情况下,如果输入的网址并没有特别指明端口,那么浏览器就会使用 HTTP 默认的 80 端口。

  4. 等待 TCP 队列。现在,IP 地址和端口号都已经准备好了,下一步是不是可以建立 TCP 连接了?答案依然是,不行。Chrome 的 TCP 连接有个机制,同一个域名下面同时最多只能建立 6 个 TCP 连接,如果同一域名下面同一时刻突然冒出来 10 个连接请求,那么其中 4 个就会进入排队状态。

  5. 建立 TCP 连接。当排队等待结束之后,终于可以和服务器握手,建立连接了。

  6. 发送 Http 请求。一旦建立了 TCP 连接,浏览器就可以和服务器进行通信了。首先,浏览器会向服务器发送一个请求行,请求行里包括了请求方法、请求地址和 Http 协议的版本。发送请求行是为了告诉服务器我需要什么样的资源,浏览器在发送完请求行之后,还会以请求头的形式发送一些其他信息(比如浏览器所使用的操作系统、浏览器内核、请求的域名以及浏览器端的 Cookie 等等)。

  7. 服务器返回请求数据。历经层层困难,Http 的请求信息终于被送到了服务器,接下来,服务器就会根据浏览器的请求信息来准备相应的内容。

    首先,服务器会返回一个响应行,响应行包括了 Http 协议版本和状态码。状态码是用来告诉浏览器服务器的处理结果的。随后,正如浏览器会随同请求行发送请求头一样,服务器也会随响应行向浏览器发送一个响应头,响应头里包含了服务器自身的一些信息(比如服务器生成返回数据的时间、返回的数据类型(JSON、HTML、流媒体类型等),以及服务器需不需要在客户端保存 Cookie 信息等)。发送完响应头后,服务器就可以继续发送响应体了,通常,响应体里就包含了浏览器请求的真正数据。

HTTP 请求流程图:

Screenshot_20220211_122209.jpg

网络七层模型图:

1605493-20190312104714993-1455348835.png