5

这是一个非常非常非常常见的问题。我将这个过程分成两部分:一部分是浏览器发送请求到服务器返回数据;一部分是浏览器收到数据开始渲染返回的结果。

先上整体的一个框架:

图片描述

DNS 解析

每一个网址都有一个相对应的独特的 IP 地址,这个 IP 地址对应着host这个域名的机器,其实域名是不重要的,重要的是这个 IP 地址,由于 IP 地址这一串数字不便于记忆,因此此案有域名这个东西来帮助我们记忆。

所以,我们首先要对域名进行解析,找到网络中真正处理这个网址的机器。

DNS 解析首先会从你的浏览器的缓存中去寻找是否有这个网址对应的 IP 地址,如果没有就向OS系统的 DNS 缓存中寻找,如果没有就是路由器的 DNS 缓存, 如果没有就是 ISP 的DNS 缓存中寻找。

所以,缓存的寻找过程就是: 浏览器 -> 系统 -> 路由器 -> ISP。

如果在某一个缓存中找到的话,就直接跳到下一步。

如果都没有找到的话,就会向 ISP 或者公共的域名解析服务发起 DNS 查找请求。这个查找的过程还是一个递归查询的过程。比如当我们访问segmentfault.com, 它的寻找过程是: 根域名服务器 -> .com域名服务器 -> segmentfault.com 域名服务器 返回相对应当的 IP 地址。

TCP 连接

通过 DNS 解析,我们找到了真正处理这个网址的服务器的 IP 地址,这时候我们要和它建立连接发送数据,TCP 是最常用的建立连接的协议。TCP 协议通过三次握手建立连接。

1️⃣:客户端通过 SYN 报文段发送连接请求,确定服务端是否开启端口准备连接。状态设置为 SYN_SEND;
2️⃣:服务器如果有开着的端口并且决定接受连接,就会返回一个 SYN+ACK 报文段给客户端,状态设置为 SYN_RECV;
3️⃣:客户端收到服务器的 SYN+ACK 报文段,向服务器发送 ACK 报文段表示确认。此时客户端和服务器都设置为 ESTABLISHED 状态。连接建立,可以开始数据传输了。

发送请求

这个时候我们的客户端已经和处理这个网址的服务器建立了连接,我们终于可以请求我们想要的数据了。

我们通常的请求行是: 请求的方式 + 请求的资源的位置 + HTTP/[版本号]

比如: GET index.html HTTP/1.1

图片描述

服务端回应

服务器上有一个 Web 服务器,常用的有 Apache 等。它用来接受客户端发来的请求,对 TCP 进行处理,解析 HTTP 协议,生成 HTTP Request 对象,然后将 HTTP Request 对象发送给请求处理器,也就是我们常用的 PHP, Ruby 等这些后端程序,这些后端程序将根据 Request 对象生成相应的响应数据。

生成响应数据之后,这时候我们就要把响应数据发送给客户端了。

通常响应由: 响应行 + 响应头部 + 响应主体 组成。

响应行:HTTP/[版本号] 状态码 状态信息

比如: HTTP/1.1 200 OK

状态码分别有以下几种:
1xx - 一些信息
2xx - 成功
3xx - 重定向
4xx - 客户端错误
5xx - 服务端错误

响应头主要是服务器想设置的一些信息,比如 cookie 等。
响应主体就是要返回的资源,比如 HTML 文件。

图片描述

完成第一部分

到这里我们已经完成了第一部分,客户端已经收到了请求的资源,假设这里收到的是 HTML 文件,下一篇我们就来看看浏览器怎么渲染收到的 HTML 文件。

参考资料

Medium 整个流程

SegmentFault 整个流程

TCP 三次握手


Yawenina
2.3k 声望117 粉丝

引用和评论

0 条评论