一、域名解析
本地DNS
当一个URL输入到浏览器地址栏中,浏览器会先去本地DNS中查看是否有关于这个域名(URL)对应的IP映射,如果有,则直接获取该IP进行访问。
DNS分为
本地DNS、本地DNS服务器、根DNS服务器、顶级DNS服务器、权威DNS服务器,本地DNS是浏览网页第一个经过的点,因为它就是我们的电脑本机,其数据都存在电脑的内存和硬盘中。
本地DNS服务器
如果本地DNS中没有找到该域名对应的IP,那么浏览器会来本地DNS服务器中继续查找。
本地服务器正常都会放在公司的机房中,部分小公司会把DNS服务器嵌入到别的服务器中,以此来节省成本。
根DNS服务器
如果本地DNS服务器中,也没有找到IP,那么浏览器会来请求根DNS服务器,该服务器需要根据域名中的根域名来查找对应的顶级DNS服务器。
根域名是只访问域名中的根部,比如一个百度网址"www.baidu.com" ,其中".com"就是根域名。
根DNS服务器中并不会存储域名的IP映射,它的作用是为浏览器提供准确的顶级DNS服务器。
顶级DNS服务器
根据根DNS服务器的指引,浏览器会准确的找到根域名所对应的顶级DNS服务器。该服务器会根据二级域名来查找对应的权威DNS服务器。
二级域名是域名的中间部分,比如还是一个百度地址"www.baidu.com" ,其中"baidu.com"就是二级域名
权威DNS服务器
最终浏览器在前面层层DNS服务器的帮助下,找到了该域名对应的权威DNS服务器,在该服务器中,可以拿到访问域名对应的IP。此时虽然拿到了,但并不能直接返回给浏览器,而是要先返回给本地DNS服务器,本地DNS服务器拿到IP后,会将这个域名和IP缓存下来,然后再给到浏览器,浏览器拿到IP后就可以对该IP进行访问了。
总体流程
浏览器 → 本地缓存 → 本地DNS服务器 →(递归查询)
↓ 若未命中
本地DNS服务器 → 根DNS → TLD DNS → 权威DNS → 获取IP
↑________缓存结果_________↓
浏览器 ← IP ← 本地DNS服务器
二、建立连接
这个的建立连接是指TCP的三次握手,具体细节如下:
- 第一次握手: 浏览器向服务器发起连接请求包,包内容是SYN报文(SYN=1)和客户端的初始序列号(seq=x)。
- 第二次握手: 服务器接收到浏览器发来的请求包后,会向浏览器发送一个请求确认包,包内容SYN-ACK确认报文(SYN=1,ACK=1)、ack确认号(x+1)、服务器初始序列号(seq=y)。
- 第三次握手: 浏览器收到后,会再次向服务器端发一个ACK确认包,包内容包含ACK确认报文(ACK=1)、序列号(seq=x+1)、确认号(ack=y+1),服务器收到ACK本文后就代表连接成功,客户端和服务器端此时就能正常通讯了。
总体流程
客户端 → 服务器:SYN=1, seq=x
客户端状态:SYN-SENT
服务器 → 客户端:SYN=1, ACK=1, seq=y, ack=x+1
服务器状态:SYN-RECEIVED
客户端 → 服务器:ACK=1, seq=x+1, ack=y+1
客户端状态:ESTABLISHED
服务器状态:ESTABLISHED(收到ACK后)
三、发送请求
浏览器会根据网页所需要的资源需求(图片、JavaScript脚本、css文件、接口等),构建HTTP请求报文并发送给服务器。
四、处理请求
服务器会根据请求报文的内容,来准备客户端所需要的资源,如果是接口数据,就去数据库中查找并整理好,如果是获取文件,就去服务器读取该文件。
五、响应请求
服务器处理完请求后,会构建HTTP响应报文(状态码、响应头、响应体等),最终将报文响应到客户端。
六、渲染页面
浏览器收到服务器的响应后,开始渲染页面
- 渲染HTML:浏览器接收并解析HTML文档,构建HTML DOM树。
- 渲染CSS:浏览器解析CSS样式表,构建CSSOM树。
- 合成渲染树:将HTML DOM树和CSSOM树合并成渲染树,渲染树只包含可见的元素和样式信息。
- 绘制和布局:根据渲染树,将HTML和CSS渲染到页面上。
- 执行JavaScript:如果页面中有JavaScript代码,浏览器会按顺序执行JavaScript代码。
七、关闭连接
至此,从输入URL到页面展示的整体任务完成了,客户端或服务器端开始申请关闭连接,这个过程其实就是四次挥手,具体步骤如下(这里的例子主动方是客户端,被动方是服务器端):
- 第一次挥手: 客户端向服务器端发送FIN包(FIN=1)和序列号(seq=u),请求关闭连接。
- 第二次挥手: 服务器端收到关闭请求后,给客户端发送ACK包(ACK=1)和确认号(ack=u+1)。
- 第三次挥手: 服务器端再次向客户端发送关闭请求,携带FIN包(FIN=1)和序列号(seq=k)。
- 第四次挥手: 客户端收到服务器端发送的确认包和关闭请求,会回应服务器端一个ACK包(ACK=1)和确认号(ack=k+1)。
总体流程
主动方(客户端) 被动方(服务器)
---------- 第一次挥手:FIN=1, seq=u ----------→
(状态:FIN-WAIT-1) (状态:ESTABLISHED)
←--------- 第二次挥手:ACK=1, ack=u+1 ----------
(状态:FIN-WAIT-2) (状态:CLOSE-WAIT)
←--------- 第三次挥手:FIN=1, seq=v ----------
(状态:TIME-WAIT) (状态:LAST-ACK)
---------- 第四次挥手:ACK=1, ack=v+1 ----------→
(等待2MSL后关闭) (状态:CLOSED)