从输入 url 到页面展示到底发生了什么
- 查找缓存
- DNS 域名解析
- tcp 三次握手
- tcp 四次挥手
- html 渲染
查找缓存
- 查询浏览器缓存:当你输入一个域名后,浏览器会首先检查自己的缓存,看是否已经解析过该域名的IP地址。如果缓存中有,解析过程结束。
- 浏览器缓存域名也是有限制的,不仅浏览器缓存大小有限制,而且缓存时间也有限制,通常情况下为几分钟到几小时不等,域名被缓存的时间限制可以通过 TTL 属性来设置。缓存时间长了,一旦域名被解析到的 ip 有变化,会导致被客户端缓存的域名无法解析到变化后的 ip 地址,以致该域名不能正常解析,这段时间有一部分客户无法访问网站;缓存时间短了,会导致客户每次访问网站都要重新解析一次域名
- 查询操作系统的DNS缓存:如果在浏览器缓存中找不到对应的IP地址,浏览器会向操作系统发出DNS解析请求。操作系统会检查自己的DNS缓存,看是否已经解析过该域名。
- 查询OS的hosts文件:如果在操作系统的DNS缓存中找不到对应的IP地址,操作系统会检查自己的hosts文件,看是否有该域名的映射信息。hosts文件是一个本地的文本文件,可以手动添加域名和IP地址的映射关系。
- 例如,我们在测试时可以将一个域名解析到一台测试服务器上,这样不用修改任何代码就能测试到单独服务器上的代码的业务逻辑是否正确。正是因为有这种本地 DNS 解析的规程,所以有黑客就可能通过修改用户的域名来把特定的域名解析到他指定的 IP 地址上,导致这些域名被劫持。
- 路由器缓存:如果在操作系统的hosts文件中找不到对应的IP地址,操作系统会将DNS解析请求发送给家庭路由器。家庭路由器也有一个DNS缓存,用于存储最近解析过的域名和IP地址。以上均为客服端的DNS缓存
- ISP(互联网服务提供商)DNS缓存。当在用户客服端查找不到域名对应IP地址,则将进入ISP DNS缓存中进行查询。比如你用的是电信的网络,则会进入电信的DNS缓存服务器中进行查找;
- 当以上均未完成,本地域名服务器就把请求发给根域名服务器
DNS 域名解析
- 本地 DNS 服务器向根域名服务器发起一个 DNS 查询
- 根域名服务器返回本地 DNS 服务器一个顶级 DNS 服务器地址 (.com、.cn、.org 等)
- 本地 DNS 服务器获得顶级 DNS 服务器发送解析请求
- 顶级 DNS 服务器接受请求查询并返回此域名对应的 Name Server 域名服务器的地址。这个 Name Server 域名服务器的地址就是我要访问的网站域名提供商的服务器,该域名的解析任务就是由域名提供商的服务器来完成。
- Name Serve 服务器会查询存储的域名和 ip 的映射关系表,再把查询出来的域名和 IP 地址等信息,连同一个 TTL 值返回给本地 DNS 服务器
- 返回的该域名的 IP 地址和 TTL 值,本地 DNS 服务器存这个域名和 ip 地址的对应关系,缓存时间由 TTL 值控制
- 把解析接口返回给本地电脑,本地电脑根据 TTL 值缓存在本地系统缓存中,域名解析过程结束
tcp 三次握手
定义: 三次握手其实就是建立一个TCP连接时,需要客户端和服务器总共发送三个包,进行三次握手的主要作用就是为了确定客户端和服务端的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上就是连接服务器指定端口、建立tcp连接、并同步连接双方的序列号和确定号、交换tcp窗口大小信息。
位码即tcp标志位6种: 1、SYN(synchronous建立联机)2、 ACK(acknowledgement 确认)3、PSH(push传送) 4、FIN(finish结束) 5、 RST(reset重置) 6、URG(urgent紧急)
sequence number: 表示这个tcp包的序列号。tcp协议拼凑接收到的数据包时,根据seq来确定顺序,并且能够确定是否有数据包丢失。所以下一个实际有数据的传输,会依旧从上一次发送 ACK 的数据包的 seq 开始)
acknowledge number: 表示这个包的确认号。首先意味着已经收到对方了多少字节数据,其次告诉对方接下来的包的seq要从ack确定的数值继续接力。
- 第一次握手:主机 A 发送位码为 SYN=1,随机产生 seq number=1234567 的数据包到服务器,主机 B 由 SYN=1 知道,A 要求建立联机; 此时客户端处于 SYN_SENT 状态。
- 第二次握手,主机 B 收到请求后要确认联机信息,向 A 发送 ack number=(主机 A 的 seq+1),SYN=1,ACK=1,随机产生 seq number=7654321 的包; 此时服务器处于 SYN_RCVD 的状态。
- 第三次握手:主机 A 收到后检查 ack number 是否正确,即第一次发送的 seq number+1,以及位码 ACK 是否为 1,若正确,此时客户端处于 ESTABLISHED 状态。主机 A 会再发送 ack number=(主机 B 的 seq+1),ACK=1,主机 B 收到后确认 seq 值与 ACK=1 则连接建立成功。
三次握手时最后一次握手为什么回复 seq=x+1
TCP 协议规定 SYN=1 报文虽然不携带数据, 但是也要消耗 1 个序列号。ACK 报文段可以携带数据、如果不携带数据不消耗序号
为什么需要三次握手,两次不行么
- 第一次握手:客户端发送网络包,服务端收到。得出结论是:客户端发送能力 ok,服务端接收能力 OK
- 第二次握手:服务端发送网络包,客户端收到。客户端得出的结论是:服务端接收、发送能力正常。服务端得出结论是:客户端的发送能力正常,接收能力还不知道。
- 第三次握手:客户端发包,服务端收到。这样服务端得出的结论是客户端的接收、发送能力正常,自己的发送、接收能力也正常。
两次握手则会出现以下情况
客户端发送请求连接、但因报文请求丢失。客户端又发送了一次请求,服务端收到确认、建立连接,数据传输完毕后,释放连接。客户端发送可两次请求连接第一次丢失、第二次到达了服务端,但是第一个丢失的报文段只是因为某个网络节点长时间滞留、延误连接释放了以后的某个时间才到达服务端,此时服务端误认为客户端又发送了一次请求,于是向客户端发送确认报文、同意建立连接。不采用三次握手、服务端只要发送就建立连接了,此时客户端忽略服务端发送的数据也不会发送数据,服务端一致等待客户端发丝数据,从而浪费资源
三次握手可以携带数据么
- 第三次握手是可以携带数据的,第一次、第二次是不可以携带数据的
第一次握手携带数据的话,如果有人恶意攻击服务器,每次都在第一次握手中的syn报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,疯狂重复发SYN报文的话,这会让服务器花费很多时间、内存空间来接收这些报文 第三次的话客户端已经处于ESTABLISHED状态,对于客户端来说他已经建立连接了并且知道了服务端接收、发送能力正常。所以可以携带数据
TCP 四次挥手
- 第一次挥手: 客户端发送一个 FIN=1 报文并初始化一个 seq=x 的值给服务端用来关闭客户端到服务度的数据传送,客户端进入 FIN_WAIT_1 状态
- 第二次挥手: 服务端回复客户端发送的 tcp 断开报文,其中包含 ACK、seq。seq 序列号,是由回复端随机生成的、ACK 字段数值是在客户端发过来的 seq 序列号基础上加 1 进行回复,以便客户端收到信息时,知晓自己的 TCP 断开请求已经得到验证(ACK=x+1、seq=y)服务端进入 CLOSE_WAIT 状态;
- 第三次挥手: 服务端在回复客户端的 tcp 断开请求后、不会马上进行 tcp 连接的断开、服务端会先确保数据是否已传送完毕、一旦确认数据传送完毕、就会将回复报文的 FIN 字段设置为 1,并产生 seq 序列号。(FIN=1、ACK=x+1、seq=z z 是由服务端随机生成)服务端进入 LAST_ACK 状态;
- 第四次挥手: 客户端收到服务端的断开请求后:客户端进入 TIME_WAIT 状态并会回复服务端的断开请求包含随机生成的 seq 字段和 ACK 字段,ACK 字段会在服务端的 TCP 断开链接请求的 seq 字段基础上+1、从而完成服务端的验证回复(FIN=1、ACK=z+1、seq=h )服务端进入 CLOSED 状态,完成四次挥手。
这个时候客户端进入TIME_WAIT需要足够的等待时间、具体来说是2个MSL,在这段时间如果客户端没有收到服务端的重发的请求,那么表示ACK成功到达、挥手结束,否则客户端重发ACK
等待 2 个 MSL 的意义
如果不等待、客户端直接跑路、当服务端还有数据包要给客户端并还在路上的时候,如客户端的端口此时刚好被新应用占用、那么直接接受到了无用的数据包造成数据混乱。
- 1 个 MSL 确保四次挥手中的主动关闭方最后的 ACK 报文能达到对端
- 1 个 MSL 确保对端没有收到 ACK 重传的 FIN 报文可以到达
为什么挥手不是三次
因为在服务端收到客户端发送的 TCP 断开链接的请求后,往往不会立即返回 FIN,必须等到服务端将所有的报文发送完毕后才能发送 FIN。因此会先发一个 ACK 表示已收到客户端的 FIN,延迟一段时间才发 FIN。这就造成了四次挥手
如果三次挥手有什么问题?
等于说服务端收到客户端的 FIN 后、将 FIN 和 ACK 合并到一次挥手,等服务端将所有的数据报文发送完毕这个时候长时间的延迟可能会导致客户端误以为 FIN 没有到达服务端,从而让客户端不断的重发 FIN
浏览器渲染
- 解析 html 标签构建 DOM 树
- 解析 css 标签,构建 CSSOM 树
- 把 DOM 树和 CSSOM 树组合成渲染树(render tree)
- 在渲染树的基础上进行布局,计算每个节点的几何结构
- 调用 CPU 绘制,合成图层,显示在屏幕上