1. 前言

虽然计算机网络是后端开发过程中必须要接触的模块,但是计算机网络相关的面试题大多都偏向理论,为了更好的理解在开发过程中计算机网络交互的作用,本小节会介绍一道网络相关的高频整合题目。

2. 在浏览器输入了一个 URL 后发生了什么

面试官提问: 当你在浏览器中输入了一个网址URL,例如http://www.imooc.com并且按下回车到页面展示内容的这个过程,发生了什么?可以从浏览器、服务器、计算机网络相关尝试分析。

图片描述

2.1 DNS域名解析

题目解析:输入 URL 之后,浏览器做的第一件事情就是 DNS 域名解析。

在之前的小节,我们分析五层网络模型时就知道了数据链路层传输的帧,并不是通过字符串 “http://imooc.com” 寻找到目标主机,而是通过 MAC 地址找到目标主机的硬件地址,要通过 ARP 协议解析获取 MAC 地址,我们需要目标主机的 IP 地址,所以问题是如何通过域名获取对应 IP 地址。

所以第一个步骤,我们需要获取域名对应的IP地址,会经过以下几个步骤:

(1)访问 Hosts 文件
浏览器会首先查看本机的 Hosts 文件,是否已经存在映射关系。
Hosts文件是用来存储常用的域名和对应IP地址关系的关联文件,例如在Hosts文件中存储了"www.imooc.com" -> "204.1.17.89",那么我们不需要访问DNS服务器即可获取百度域名对应的IP地址。

(2)访问本地缓存
如果 Hosts 文件中不存在映射关系,浏览器(例如Chrome)会再查看浏览器本地的缓存,是否存在映射关系。

(3)访问 DNS 服务器

图片描述

(图1:域名到IP的解析模型)

DNS 解析的过程简单来看,是从"我的电脑"传输域名"www.imooc.com"到 DNS 服务器,解析生成IP后返回给"我的电脑"。但是面试官一般会接着询问 DNS 解析的详细过程,依次考察候选人的知识深度。

图片描述

(图2:DNS 迭代查询的具体过程)

步骤(1):浏览器会向本地 DNS 服务器发送域名报文。

步骤(2):本地 DNS 接收报文之后,会将请求转发到根 DNS 服务器。

步骤(3):根 DNS 服务器通过".com"后缀返回 com 顶级域名服务器的IP地址205.0.1.2

步骤(4):本地 DNS 服务器带着域名访问IP:205.0.1.2顶级域名服务器。

步骤(5):com 顶级域名服务器根据后缀"imooc.com",返回 IP 地址206.0.1.3

步骤(6):本地 DNS 服务器带着域名访问IP206.0.1.3二级域名服务器。

步骤(7):二级域名服务器通过www.imooc.com查询到了域名对应的实际IP地址210.1.17.89,返回给本地 DNS 服务器。

步骤(8):本地 DNS 服务器透传IP210.1.17.89返回给"我的电脑"。

2.2 建立 TCP 连接

在经过 DNS 解析之后,浏览器已经获取了对应网站的 IP 地址,通过三次握手连接到网站服务器,这个步骤中,我们可以给面试官画出简化后的三次握手过程:

图片描述

TCP三次握手

(1)客户端发送一个带有 SYN 标记位的数据包(syn=J)到服务器,然后进入 SYN_SENT 状态;

(2)服务器收到 SYN 包,需要确认客户端的 SYN(赋值ack=J+1),然后自己也发送一个 SYN 包(syn=K),服务器进入 SYN_RCVD 状态;

(3)客户端收到服务器的 SYN+ACK 包,向服务器端发送确认包,即ack=K+1,发送完成之后,两边都进入 ESTABLISHED 建立连接状态。

2.3 发送 HTTP 请求

TCP 三次握手之后,客户端和服务器端成功建立了连接,之后浏览器会向服务器特定端口发送HTTP请求。

图片描述

(https://imooc.com URL的请求报文)

以 Chrome 浏览器为例,按下 F12 即可进入开发者模式,Network 一栏查看HTTP请求的具体报文。

一个 HTTP 报文由请求行(Request Line)、请求头部(Request Headers)、空行(Blank Line)以及请求体(Request Body)构成,请求行中规定了请求方法、URI 以及 HTTP 的版本,关于每个字段的详细解释,之前的小节已经进行了阐述。

2.4 服务器端解析请求

当一个 HTTP 请求打进服务器之后,一般的流程是:网关层(例如Ngnix)最先获取请求,然后路由转发到具体的Web服务,经过一段业务逻辑之后,可能还会查询数据库,最后将处理的结果返回给浏览器客户端。

对于后端开发程序员来说,日常的工作就集中在服务器端,特别是流程图中的"Web业务服务"这块,例如基于 Spring 框架、Django 框架或者ThinkPHP 框架进行业务逻辑开发和上线。

图片描述

(HTTP 请求进入服务器端后的解析流程图)

2.5 返回 HTTP 响应

服务器端处理业务结果之后,也要返回 HTTP 响应,HTTP 响应由状态行(Status Line)、响应头部(Response Headers)、空行(Blank Line)以及响应体(Response Body)构成,关于每个部分的细节也不再赘述。需要特别注意的是,响应体中的各种错误码定义:

状态类型 代表状态码和含义 说明
1xx 100 Continue 服务器收到了客户端的请求行和头部信息,告诉
客户端继续发送数据部分。
2xx 200 OK 请求成功
3xx 301 Moved Permanently 资源被转移了,请求将被重定向
4xx 404 Not Found 资源没找到
5xx 500 Internal Server Error 服务器内部错误

2.6 TCP四次挥手

当浏览器获取了域名对应的页面信息,为了避免服务器和客户端双方的资源损耗,客户端会请求断开 TCP 连接,和三次握手的过程相似,TCP 四次挥手的过程可以总结为:

(1)第一次请求:客户端请求断开FIN,携带信息seq=u;

(2)第二次请求:服务器确认客户端的断开请求 ACK ,携带信息ack=u+1,seq=v;

(3)第三次请求:服务器请求断开 FIN ,携带信息seq=w,ACK,ack=u+1;

(4)第四次请求:客户端确认服务器的断开 ACK ,携带信息ack=w+1,seq=u+1。

图片描述

(TCP四次挥手示意图)

2.7 浏览器解析 HTML

服务器返回给客户端的是 HTML 以及 CSS、Javascript 代码,要展示为静态页面,还需要经过浏览器的解析行为。

浏览器内核引擎解析 HTML 文档并且将标签转换为 DOM(Document Object Model,文档对象模型)树的 DOM 节点,不同浏览器的渲染解析流程大同小异。

同时,浏览器内核引擎还会解析 CSS 生成 CSS 规则树,按照从右到左的顺序读取选择器。

另外,在浏览器中还有个"JS脚本解析器",解析 HTML 和 CSS 是多线程同时执行的,CSS 解析失败不会影响 HTML 内容的解析,但是如果 JS 脚本解析过程中触发了异常,会直接终止 HTML 内容的解析。关于更详细的解析动作,作为后端开发,我们不需要了解太多,这块也不会作为面试考察的内容。

3.小结

本节中和大家讲解了"我们在浏览器中输入一个URL,具体发生了什么",整个过程中分析了应用层(HTTP、DNS)、传输层(TCP)、网络层(IP)等网络分层的各个协议的作用,也对服务器解析HTTP的基本流程进行了阐述,本小节需要大家掌握访问 URL 时每个步骤的基本功能,能够通过对调用链路的分析,向面试官展示自己的计算机网络功底。