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 服务器
DNS 解析的过程简单来看,是从"我的电脑"传输域名"www.imooc.com"
到 DNS 服务器,解析生成IP后返回给"我的电脑"。但是面试官一般会接着询问 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 地址,通过三次握手连接到网站服务器,这个步骤中,我们可以给面试官画出简化后的三次握手过程:
(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请求。
以 Chrome 浏览器为例,按下 F12 即可进入开发者模式,Network 一栏查看HTTP请求的具体报文。
一个 HTTP 报文由请求行(Request Line)、请求头部(Request Headers)、空行(Blank Line)以及请求体(Request Body)构成,请求行中规定了请求方法、URI 以及 HTTP 的版本,关于每个字段的详细解释,之前的小节已经进行了阐述。
2.4 服务器端解析请求
当一个 HTTP 请求打进服务器之后,一般的流程是:网关层(例如Ngnix)最先获取请求,然后路由转发到具体的Web服务,经过一段业务逻辑之后,可能还会查询数据库,最后将处理的结果返回给浏览器客户端。
对于后端开发程序员来说,日常的工作就集中在服务器端,特别是流程图中的"Web业务服务"这块,例如基于 Spring 框架、Django 框架或者ThinkPHP 框架进行业务逻辑开发和上线。
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。
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 时每个步骤的基本功能,能够通过对调用链路的分析,向面试官展示自己的计算机网络功底。