3. 完整的HTTP请求流程

HTTP是一个简单的请求-响应协议,它通常运行在TCP之上,是一种允许浏览器向服务器获取资源的协议,是 Web 的基础,通常由浏览器发起请求,用来获取不同类型的文件,例如 HTML 文件、CSS 文件、JavaScript 文件、图片、视频等。此外,HTTP 也是浏览器使用最广的协议

在今天这篇文章中,我将通过分析一个 HTTP 请求过程中每一步的状态来带梳理完整的 HTTP 请求过程。

1. 构建请求行

首先,浏览器构建请求行信息(如下所示),构建好后,浏览器准备发起网络请求。

请求方法   请求URL  HTTP协议及版本
GET /  index.html   HTTP1.1

2. 查找缓存

在真正发起网络请求之前,浏览器会先在浏览器缓存中查询是否有要请求的文件,其中,浏览器缓存是一种在本地保存的资源副本,以供下次请求时直接使用的技术。

当浏览器发现请求的资源已经在浏览器缓存中存有副本,它就会拦截请求,返回该资源的副本,并直接结束请求,而不会再去源服务器重新下载,这样做的好处是:

  1. 缓解服务器压力,提升性能(获取资源的耗时更短了)

  2. 对于网站来说,缓存是实现资源加载的重要组成部分。

当然,如果缓存查找失败,就会进入网络请求过程了。要详细了解缓存,参考xxx

3. DNS解析IP地址

不过,先不急,在了解网络请求之前,我们需要先看看HTTP和TCP的关系。因为浏览器使用HTTP协议作为应用层协议,用来封装请求的文本信息,并使用TCP/IP作传输层协议将它发到网络上,所以在HTTP工作开始之前,浏览器需要通过TCP与服务器建立连接。也就是说HTTP的内容是通过TCP的传输数据阶段来实现的,你可以结合下图更好地理解这两种的关系。

image-20200823122439271.png

那接下来可以思考这么”一连串”问题:

  1. HTTP网络请求的第一步是做什么呢?结合上图看,是和服务器建立TCP连接

  2. 那建立连接的信息都有了吗?在上一篇xxx文章中,我们讲到建立TCP连接的第一步就是需要准备IP和端口号。

  3. 那怎么获取IP和端口号呢?这得看看我们现在有什么,我们有一个目标URL地址,那是否可以利用URL地址来获取IP和端口号信息呢?

在上一篇xxx文章中,我们介绍过数据包都是通过 IP 地址传输给接收方的。由于 IP 地址是数字标识,比如百度网站的 IP 是 39.106.233.176, 难以记忆,但使用百度的域名(baidu.com)就好记多了,所以基于这个需求又出现了一个服务,负责把域名和 IP 地址做一一映射关系。这套域名映射为 IP 的系统就叫做“域名系统”,简称 DNS(Domain Name System)

所以,这样一路推导下来,你会发现在第一步浏览器会请求 DNS 返回域名对应的 IP。当然浏览器还提供了 DNS 数据缓存服务,如果某个域名已经解析过了,那么浏览器会缓存解析的结果,以供下次查询时直接使用,这样也会减少一次网络请求。

拿到 IP 之后,接下来就需要获取端口号了。通常情况下,如果 URL 没有特别指明端口号,那么 HTTP 协议默认是 80 端口。

4. 等待TCP队列

现在已经把端口和 IP 地址都准备好了,那么下一步是不是可以建立 TCP 连接了呢?

答案依然是“不行”,chrome有个机制,同一个域名 同时最多只能建立6个TCP连接,如果在同一域名下同时有10个请求发生,那么4个请求会进入排列等待状态,直至进行中的请求完成。

当然,如果请求的数量少于6,会直接进入下一步,建立TCP连接。

5. 建立TCP连接

排队等待结束之后,终于可以快乐地和服务器握手了,在 HTTP 工作开始之前,浏览器通过 TCP的三次握手与服务器建立连接。

6. 发送HTTP请求

一旦建立了TCP连接,浏览器就可以呃服务器进行通信了,而HTTP中的数据正是这个通信过程中传输的。

image-20200823213303163.png

首先浏览器会向服务器发送请求行,它包括了请求方法、请求URL、和HTTP协议版本。

发送请求行,就是告诉服务器需要什么资源,最常见的请求方法是GET,比如,直接在浏览器地址栏中输入百度的域名(baidu.com),这就告诉服务器要GET它的首页资源。

另外一个常见的请求方法是POST,它用于发送一些数据给服务器,比如登录一个网站,就需要通过POST方式吧用户的信息发送给服务器的数据库保存起来,这里浏览器准备的数据是通过请求体来发送。

在浏览器发送请求命令之后,还要以请求头形式发送其他一些信息,把浏览器的一些基础信息告诉服务器,比如浏览器所使用的操作系统,浏览器内核,以及当前请求的域名信息,浏览器端的Cookie信息等等。

服务器处理HTTP请求流程

历经千辛万苦,HTTP的请求信息终于被送达了服务器,接下来,服务器会根据浏览器的请求信息来准备相应的内容。

7. 返回响应

一旦服务器处理结束,便可以返回数据给浏览器了。

image-20200823214513129.png

首先服务器会返回响应行,包括协议版本和状态码

随后,服务器也会随同响应向浏览器发送响应头。响应头包含了服务器自身的一些信息,比如服务器生成返回数据的时间、返回的数据类型(JSON、HTML、流媒体等类型),以及服务器要在客户端保存的 Cookie 等信息。

发送完响应头后,服务器就可以继续发送 响应体的数据,通常,响应体就包含了HTML的实际内容。

以上这些就是服务响应浏览器的具体过程

8. 断开连接

通常情况下,一旦服务向客户端返回了请求数据,它就要关闭TCP连接,不够浏览器或服务器在其头信息中加入了:

Connection:keep-alive

那么 TCP 连接在发送后将仍然保持打开状态,这样浏览器就可以继续通过同一个 TCP 连接发送请求。保持 TCP 连接可以省去下次请求时需要建立连接的时间,提升资源加载速度。比如,一个 Web 页面中内嵌的图片就都来自同一个 Web 站点,如果初始化了一个持久连接,你就可以复用该连接,以请求其他资源,而不需要重新再建立新的 TCP 连接。

9. 重定向

到这里似乎请求流程快结束了,不过还有一种情况你需要了解下,比如当你在浏览器中打开 baidu.com 后,你会发现最终打开的页面地址是 https://www.baidu.com这两个 URL 之所以不一样,是因为涉及到了一个重定向操作。

image-20200823215442020.png

从图中你可以看到,响应行返回的状态码是 301,状态 301 就是告诉浏览器,我需要重定向到另外一个网址,而需要重定向的网址正是包含在响应头的 Location 字段中,接下来,浏览器获取 Location 字段中的地址,并使用该地址重新导航,这就是一个完整重定向的执行流程。这也就解释了为什么输入的是 baidu.com,最终打开的却是 https://www.baidu.com 了。

至此,整个HTTP请求流程已经结束。

流程总结

image-20200823214232818.png


评论 抢沙发

表情
首页上一页12下一页尾页