一文带你看懂从URL输入到页面呈现发生了什么

前言

URL输入到页面呈现到底发生了什么呢?这怕是已经被问烂的问题了,其中涉及的内容或浅或深,可以说是非常经典了,这里我们盘点一下,给出个还算过得去的答案。

从URL输入到响应

首先,当我们输入了一个URL时,浏览器会生成请求行,主要有三个部分,请求方法,根路径以及HTTP版本,典型如:

GET / HTTP/1.1

请求之后呢,我们首先会去强缓存看有没有命中,有的话就不需要发送HTTP请求,关于HTTP缓存前文有详述,这里不在介绍。

接下来,如果没有命中强缓存,就开始进入DNS解析阶段,简单地说就是有个域名系统存储着IP与域名的映射。同样的,如果浏览器缓存了DNS域名解析,即该域名已经被解析过了,它同样会在缓存中读到,而不需要在经过DNS解析。

拿到IP之后,浏览器会尝试建立TCP连接,无论是HTTP1.0,1.1,还是2.0,TCP连接都是传输层的通信协议,当然对于浏览器来说同时存在的TCP连接个数是有限的,如Chrome同一域名下最多只能有6个TCP连接,超过的话只能等待了。

进入了连接建立阶段,可能就到了大家耳熟能详的三次握手等阶段了。关于三次握手其实是通过3个数据包的发送确立可靠的TCP连接是否建立的过程,那么为什么需要三次呢?首先是客户端向服务端发送了一个SYN报文,指明客户端的初始化序列号,并把自己置于SYN_SEND状态,其次服务端收到客户端的SYN保温之后,会以自己的SYN报文作为回应,同时也指定自己的初始化序列号,处于SYN_REVD的状态。最后客户端收到了SYN报文后,会发送一个ACK报文,标识收到了服务端的SYN报文,此时客户端处于ESTABLISHED状态,而服务器收到ACK报文后也会处于ESTABLISHED状态,连接建立。
在这里插入图片描述

简单说一下,第一次握手实现的让服务端知道客户端发送能力和服务端接受能力的确认,第二次握手实现的是客户端知道双方首发能力的确认,而最后一次握手实现的是服务端知道自己发送能力和服务端接收能力的确认,因此一次都不可少。

数据传输过程中收到包的一方必须发送确认让发送方知道发送成功,否则重发,这也是TCP连接可靠性的重要举措之一,而保证连接可靠性的最后一步就是四次挥手断开连接。

首先客户端和服务器都可以主动发起回收动作,假如是客户端发起的话,他会发送一个FIN报文,处于FIN_WAIT1的状态;服务端收到该报文后,会发生ACK报文,并表明自己已经收到了客户端报文,此时服务端处于CLOSE_WAIT状态;接着如果服务端也想断开连接了,他也会发送FIN报文,此时他会处于LAST_ACK状态,客户端收到了这个保温之后,一样会发送一个ACK报文回应,此时会处于TIME_WAIT状态,这个状态会延迟2msl在保证服务端收到ACK报文之后才会进入CLOSED状态,而收到ACK报文的服务端自然就处于CLOSED状态了。

那么如果最后的ACK报文丢失了怎么办呢?服务端怎么确认客户端有没有收到FIN报文呢?而客户端又怎么确认服务端有没有收到ACK报文呢?其实这和最后2msl的等待有关,如果最后的ACK报文没有接收到,服务端会在2msl之内重发FIN并保证客户端接收到了,这样的话客户端也知道自己的ACK可能丢失,同时因为他没有处于关闭状态,自然可以再次发送ACK报文。

简单的说完了TCP连接建立。接着到了HTTP请求阶段,浏览器发送请求需要之前说过的请求行,请求头和请求体,请求体并不是必须的,同样请求到了服务器,服务器处理之后会返回响应,也包括相应行,响应头和响应体。在相应完成之后TCP连接是否断开与请求或响应头中的Connection: Keep-Alive有关,这表示持久连接的意思。

解析与渲染

如果拿到的响应头中Content-Type的值是text/html,那么接下来就是浏览器的解析和渲染了。

解析主要分为Dom树的构建,CSS样式计算以及布局树的生成。这里暂不讨论。

渲染主要分为图层树的建立,即使上面DOM节点有了,样式和位置信息娱乐,但并不意味之可以开始绘制页面了,还有一些很复杂的场景需要图分层,然后渲染引擎会把图层绘制拆分成一个个绘制指令,生成图块和位图。
在这里插入图片描述
这一块可以参考下文

发布了346 篇原创文章 · 获赞 330 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43870742/article/details/104027314